build: Move gtk/tests to testsuite/gtk
authorBenjamin Otte <otte@redhat.com>
Tue, 14 May 2013 23:48:18 +0000 (01:48 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 15 May 2013 13:37:16 +0000 (15:37 +0200)
87 files changed:
configure.ac
gtk/Makefile.am
gtk/tests/Makefile.am [deleted file]
gtk/tests/accel.c [deleted file]
gtk/tests/accessible.c [deleted file]
gtk/tests/action.c [deleted file]
gtk/tests/bitmask.c [deleted file]
gtk/tests/builder.c [deleted file]
gtk/tests/cellarea.c [deleted file]
gtk/tests/crossingevents.c [deleted file]
gtk/tests/defaultvalue.c [deleted file]
gtk/tests/entry.c [deleted file]
gtk/tests/expander.c [deleted file]
gtk/tests/file-chooser-test-dir/empty [deleted file]
gtk/tests/file-chooser-test-dir/text.txt [deleted file]
gtk/tests/filechooser.c [deleted file]
gtk/tests/filtermodel.c [deleted file]
gtk/tests/floating.c [deleted file]
gtk/tests/grid.c [deleted file]
gtk/tests/gtkmenu.c [deleted file]
gtk/tests/gtktreemodelrefcount.c [deleted file]
gtk/tests/gtktreemodelrefcount.h [deleted file]
gtk/tests/keyhash.c [deleted file]
gtk/tests/liststore.c [deleted file]
gtk/tests/modelrefcount.c [deleted file]
gtk/tests/object.c [deleted file]
gtk/tests/objects-finalize.c [deleted file]
gtk/tests/papersize.c [deleted file]
gtk/tests/rbtree.c [deleted file]
gtk/tests/recentmanager.c [deleted file]
gtk/tests/regression-tests.c [deleted file]
gtk/tests/sortmodel.c [deleted file]
gtk/tests/stylecontext.c [deleted file]
gtk/tests/templates.c [deleted file]
gtk/tests/testing.c [deleted file]
gtk/tests/textbuffer.c [deleted file]
gtk/tests/textiter.c [deleted file]
gtk/tests/treemodel.c [deleted file]
gtk/tests/treemodel.h [deleted file]
gtk/tests/treepath.c [deleted file]
gtk/tests/treestore.c [deleted file]
gtk/tests/treeview-scrolling.c [deleted file]
gtk/tests/treeview.c [deleted file]
gtk/tests/window.c [deleted file]
testsuite/Makefile.am
testsuite/gtk/Makefile.am [new file with mode: 0644]
testsuite/gtk/accel.c [new file with mode: 0644]
testsuite/gtk/accessible.c [new file with mode: 0644]
testsuite/gtk/action.c [new file with mode: 0644]
testsuite/gtk/bitmask.c [new file with mode: 0644]
testsuite/gtk/builder.c [new file with mode: 0644]
testsuite/gtk/cellarea.c [new file with mode: 0644]
testsuite/gtk/crossingevents.c [new file with mode: 0644]
testsuite/gtk/defaultvalue.c [new file with mode: 0644]
testsuite/gtk/entry.c [new file with mode: 0644]
testsuite/gtk/expander.c [new file with mode: 0644]
testsuite/gtk/file-chooser-test-dir/empty [new file with mode: 0644]
testsuite/gtk/file-chooser-test-dir/text.txt [new file with mode: 0644]
testsuite/gtk/filechooser.c [new file with mode: 0644]
testsuite/gtk/filtermodel.c [new file with mode: 0644]
testsuite/gtk/floating.c [new file with mode: 0644]
testsuite/gtk/grid.c [new file with mode: 0644]
testsuite/gtk/gtkmenu.c [new file with mode: 0644]
testsuite/gtk/gtktreemodelrefcount.c [new file with mode: 0644]
testsuite/gtk/gtktreemodelrefcount.h [new file with mode: 0644]
testsuite/gtk/keyhash.c [new file with mode: 0644]
testsuite/gtk/liststore.c [new file with mode: 0644]
testsuite/gtk/modelrefcount.c [new file with mode: 0644]
testsuite/gtk/object.c [new file with mode: 0644]
testsuite/gtk/objects-finalize.c [new file with mode: 0644]
testsuite/gtk/papersize.c [new file with mode: 0644]
testsuite/gtk/rbtree.c [new file with mode: 0644]
testsuite/gtk/recentmanager.c [new file with mode: 0644]
testsuite/gtk/regression-tests.c [new file with mode: 0644]
testsuite/gtk/sortmodel.c [new file with mode: 0644]
testsuite/gtk/stylecontext.c [new file with mode: 0644]
testsuite/gtk/templates.c [new file with mode: 0644]
testsuite/gtk/testing.c [new file with mode: 0644]
testsuite/gtk/textbuffer.c [new file with mode: 0644]
testsuite/gtk/textiter.c [new file with mode: 0644]
testsuite/gtk/treemodel.c [new file with mode: 0644]
testsuite/gtk/treemodel.h [new file with mode: 0644]
testsuite/gtk/treepath.c [new file with mode: 0644]
testsuite/gtk/treestore.c [new file with mode: 0644]
testsuite/gtk/treeview-scrolling.c [new file with mode: 0644]
testsuite/gtk/treeview.c [new file with mode: 0644]
testsuite/gtk/window.c [new file with mode: 0644]

index 6ee3c05731e7fda74b02c8be1aa9f57a51c9c304..7a0fbbf7ea6158cd7201e8667f6fb2c5ce4cc7aa 100644 (file)
@@ -1787,6 +1787,7 @@ tests/reftests/Makefile
 tests/visuals/Makefile
 testsuite/Makefile
 testsuite/gdk/Makefile
+testsuite/gtk/Makefile
 docs/Makefile
 docs/reference/Makefile
 docs/reference/gdk/Makefile
@@ -1816,7 +1817,6 @@ gtk/gtkversion.h
 gtk/gtk-win32.rc
 gtk/a11y/Makefile
 gtk/native/Makefile
-gtk/tests/Makefile
 libgail-util/Makefile
 modules/Makefile
 modules/engines/Makefile
index 60fbc31e186ecbcd87a75db0fee4e2b75f0e878c..a726377f185acfed8b40b6594777f0b7ec594835 100644 (file)
@@ -16,7 +16,7 @@ else
 GTK_PRINT_PREVIEW_COMMAND="evince --unlink-tempfile --preview --print-settings %s %f"
 endif
 
-SUBDIRS = a11y native . tests
+SUBDIRS = a11y native .
 
 if HAVE_PAPI_CUPS
 GTK_PRINT_BACKENDS=file,papi,cups
diff --git a/gtk/tests/Makefile.am b/gtk/tests/Makefile.am
deleted file mode 100644 (file)
index ea5b759..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-include $(top_srcdir)/Makefile.decl
-
-SUBDIRS =
-
-AM_CPPFLAGS = \
-       -I$(top_srcdir)                 \
-       -I$(top_builddir)/gdk           \
-       -I$(top_srcdir)/gdk             \
-       -I$(top_builddir)/gtk           \
-       -I$(top_srcdir)/gtk             \
-       -DSRCDIR=\""$(abs_srcdir)"\"    \
-       $(GTK_DEBUG_FLAGS)              \
-       $(GTK_DEP_CFLAGS)
-
-if OS_UNIX
-AM_CPPFLAGS += -DHAVE_UNIX_PRINT_WIDGETS
-endif
-
-DEPS = \
-       $(top_builddir)/gtk/libgtk-3.la
-
-progs_ldadd = \
-       $(top_builddir)/gtk/libgtk-3.la \
-       $(top_builddir)/gdk/libgdk-3.la \
-       $(GTK_DEP_LIBS)
-
-noinst_PROGRAMS = $(TEST_PROGS)
-
-
-TEST_PROGS                     += testing
-testing_SOURCES                         = testing.c
-testing_LDADD                   = $(progs_ldadd)
-
-TEST_PROGS                     += treemodel
-treemodel_SOURCES               = \
-                               treemodel.h \
-                               treemodel.c \
-                               liststore.c \
-                               treestore.c \
-                               filtermodel.c \
-                               sortmodel.c \
-                               modelrefcount.c \
-                               gtktreemodelrefcount.h \
-                               gtktreemodelrefcount.c
-treemodel_LDADD                         = $(progs_ldadd)
-
-TEST_PROGS                     += treeview
-treeview_SOURCES                = treeview.c
-treeview_LDADD                  = $(progs_ldadd)
-
-TEST_PROGS                     += treeview-scrolling
-treeview_scrolling_SOURCES      = treeview-scrolling.c
-treeview_scrolling_LDADD        = $(progs_ldadd) -lm
-
-TEST_PROGS                     += recentmanager
-recentmanager_SOURCES           = recentmanager.c
-recentmanager_LDADD             = $(progs_ldadd)
-
-TEST_PROGS                     += floating
-floating_SOURCES                = floating.c
-floating_LDADD                  = $(progs_ldadd)
-
-TEST_PROGS                     += accel
-accel_SOURCES                   = accel.c
-accel_LDADD                     = $(progs_ldadd)
-
-#TEST_PROGS                    += object
-#object_SOURCES                         = object.c
-#object_LDADD                   = $(progs_ldadd)
-
-# this doesn't work in make distcheck, since running
-# on a naked X server creates slightly different event
-# sequences than running on a normal desktop
-# TEST_PROGS                   += crossingevents
-#crossingevents_SOURCES                 = crossingevents.c
-#crossingevents_LDADD           = $(progs_ldadd)
-
-TEST_PROGS                     += filechooser
-filechooser_SOURCES             = filechooser.c
-filechooser_LDADD               = $(progs_ldadd)
-
-TEST_PROGS                     += builder
-builder_SOURCES                         = builder.c
-builder_LDADD                   = $(progs_ldadd)
-builder_LDFLAGS                         = -export-dynamic
-
-TEST_PROGS                     += templates
-templates_SOURCES               = templates.c
-templates_LDADD                         = $(progs_ldadd)
-
-if OS_UNIX
-#TEST_PROGS                    += defaultvalue
-#defaultvalue_SOURCES           = defaultvalue.c
-#defaultvalue_LDADD             = $(progs_ldadd)
-endif
-
-TEST_PROGS                     += textbuffer
-textbuffer_SOURCES              = textbuffer.c
-textbuffer_LDADD                = $(progs_ldadd)
-
-TEST_PROGS                     += textiter
-textiter_SOURCES                = textiter.c
-textiter_LDADD                  = $(progs_ldadd)
-
-TEST_PROGS                     += expander
-expander_SOURCES                = expander.c
-expander_LDADD                  = $(progs_ldadd)
-
-TEST_PROGS                     += action
-action_SOURCES                  = action.c
-action_LDADD                    = $(progs_ldadd)
-
-TEST_PROGS                     += stylecontext
-stylecontext_SOURCES            = stylecontext.c
-stylecontext_LDADD              = $(progs_ldadd)
-
-TEST_PROGS                     += papersize
-papersize_SOURCES               = papersize.c
-papersize_LDADD                         = $(progs_ldadd)
-
-TEST_PROGS                     += cellarea
-cellarea_SOURCES                = cellarea.c
-cellarea_LDADD                  = $(progs_ldadd)
-
-TEST_PROGS                     += treepath
-treepath_SOURCES                = treepath.c
-treepath_LDADD                  = $(progs_ldadd)
-
-TEST_PROGS                     += accessible
-accessible_SOURCES              = accessible.c
-accessible_LDADD                = $(progs_ldadd)
-
-TEST_PROGS                     += entry
-entry_SOURCES                   = entry.c
-entry_LDADD                     = $(progs_ldadd)
-
-TEST_PROGS                     += grid
-grid_SOURCES                    = grid.c
-grid_LDADD                      = $(progs_ldadd)
-
-TEST_PROGS                     += rbtree
-rbtree_CFLAGS                   = -DGTK_COMPILATION -UG_ENABLE_DEBUG
-rbtree_SOURCES                  = rbtree.c \
-                                  $(top_srcdir)/gtk/gtkrbtree.h \
-                                  $(top_srcdir)/gtk/gtkrbtree.c
-rbtree_LDADD                    = $(GTK_DEP_LIBS)
-
-TEST_PROGS                     += bitmask
-bitmask_CFLAGS                  = -DGTK_COMPILATION -UG_ENABLE_DEBUG
-bitmask_SOURCES                         = bitmask.c \
-                                  $(top_srcdir)/gtk/gtkbitmaskprivate.h \
-                                  $(top_srcdir)/gtk/gtkallocatedbitmaskprivate.h \
-                                  $(top_srcdir)/gtk/gtkallocatedbitmask.c
-bitmask_LDADD                   = $(GTK_DEP_LIBS)
-
-TEST_PROGS                     += regression-tests
-regression_tests_SOURCES        = regression-tests.c
-regression_tests_LDADD          = $(progs_ldadd)
-
-TEST_PROGS                     += keyhash
-keyhash_SOURCES                         = keyhash.c \
-                                  $(top_srcdir)/gtk/gtkkeyhash.c \
-                                  $(top_srcdir)/gtk/gtkkeyhash.h \
-                                  $(top_srcdir)/gtk/gtkresources.c \
-                                  $(top_srcdir)/gtk/gtkresources.h \
-                                  $(top_srcdir)/gtk/gtkprivate.c \
-                                  $(top_srcdir)/gtk/gtkprivate.h
-keyhash_LDADD                   = $(progs_ldadd)
-keyhash_CFLAGS                  = -DGTK_COMPILATION \
-                                  -DGTK_LIBDIR=\"$(libdir)\" \
-                                  -DGTK_DATADIR=\"$(datadir)\" \
-                                  -DGTK_DATA_PREFIX=\"$(prefix)\" \
-                                  -DGTK_SYSCONFDIR=\"$(sysconfdir)\"
-
-TEST_PROGS                     += gtkmenu
-gtkmenu_SOURCES                         = gtkmenu.c
-gtkmenu_LDADD                   = $(progs_ldadd)
-
-
-TEST_PROGS                     += objects-finalize
-objects_finalize_SOURCES         = objects-finalize.c
-objects_finalize_LDADD          = $(progs_ldadd)
-
-TEST_PROGS                     += window
-window_SOURCES                  = window.c
-window_LDADD                    = $(progs_ldadd)
-
-EXTRA_DIST +=                          \
-       file-chooser-test-dir/empty     \
-       file-chooser-test-dir/text.txt
-
--include $(top_srcdir)/git.mk
diff --git a/gtk/tests/accel.c b/gtk/tests/accel.c
deleted file mode 100644 (file)
index d7ceb94..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* accel.c - test accel parsing
- * Copyright (C) 2011 Bastien Nocera <hadess@hadess.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <gtk/gtk.h>
-#include <locale.h>
-
-static void
-test_one_accel (const char *accel,
-               const char *exp_label,
-               gboolean has_keysym)
-{
-  guint accel_key;
-  GdkModifierType mods;
-  guint *keycodes;
-  char *label, *name;
-
-  accel_key = 0;
-  gtk_accelerator_parse_with_keycode (accel,
-                                     &accel_key,
-                                     &keycodes,
-                                     &mods);
-
-  if (has_keysym)
-    {
-      guint accel_key_2;
-      GdkModifierType mods_2;
-
-      gtk_accelerator_parse (accel,
-                             &accel_key_2,
-                             &mods_2);
-      g_assert (accel_key == accel_key_2);
-      g_assert (mods == mods_2);
-    }
-
-  if (has_keysym)
-    g_assert (accel_key != 0);
-  g_assert (keycodes);
-  g_assert (keycodes[0] != 0);
-
-  label = gtk_accelerator_get_label_with_keycode (NULL,
-                                                 accel_key,
-                                                 *keycodes,
-                                                 mods);
-
-  g_assert_cmpstr (label, ==, exp_label);
-
-  name = gtk_accelerator_name_with_keycode (NULL,
-                                           accel_key,
-                                           *keycodes,
-                                           mods);
-  g_assert_cmpstr (name, ==, accel);
-
-  g_free (keycodes);
-  g_free (label);
-  g_free (name);
-}
-
-static void
-accel1 (void)
-{
-  test_one_accel ("0xb3", "0xb3", FALSE);
-}
-
-static void
-accel2 (void)
-{
-  test_one_accel ("<Primary><Alt>z", "Ctrl+Alt+Z", TRUE);
-}
-
-static void
-accel3 (void)
-{
-  test_one_accel ("KP_7", "7", TRUE);
-}
-
-static void
-accel4 (void)
-{
-  test_one_accel ("<Primary>KP_7", "Ctrl+7", TRUE);
-}
-
-static void
-accel5 (void)
-{
-  test_one_accel ("<Shift>exclam", "Shift+!", TRUE);
-}
-
-static void
-keysyms (void)
-{
-  g_assert (gdk_keyval_from_name ("KP_7") == GDK_KEY_KP_7);
-}
-
-int
-main (int   argc,
-      char *argv[])
-{
-  setlocale (LC_ALL, "en_GB.UTF-8");
-
-  gtk_test_init (&argc, &argv);
-
-  g_test_add_func ("/keysyms", keysyms);
-
-  g_test_add_func ("/accel1", accel1);
-  g_test_add_func ("/accel2", accel2);
-  g_test_add_func ("/accel3", accel3);
-  g_test_add_func ("/accel4", accel4);
-  g_test_add_func ("/accel5", accel5);
-  return g_test_run();
-}
diff --git a/gtk/tests/accessible.c b/gtk/tests/accessible.c
deleted file mode 100644 (file)
index 03668c3..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <gtk/gtk.h>
-
-static void
-test_type (GType t)
-{
-  GtkWidget *w;
-  AtkObject *a;
-
-  if (g_type_is_a (t, GTK_TYPE_WIDGET))
-    {
-      w = (GtkWidget *)g_object_new (t, NULL);
-      a = gtk_widget_get_accessible (w);
-
-      g_assert (GTK_IS_ACCESSIBLE (a));
-      g_assert (gtk_accessible_get_widget (GTK_ACCESSIBLE (a)) == w);
-
-      g_object_unref (w);
-    }
-}
-
-int
-main (int argc, char *argv[])
-{
-  const GType *tp;
-  guint i, n;
-
-  gtk_init (&argc, &argv);
-
-  tp = gtk_test_list_all_types (&n);
-
-  for (i = 0; i < n; n++)
-    test_type (tp[i]);
-
-  return 0;
-}
diff --git a/gtk/tests/action.c b/gtk/tests/action.c
deleted file mode 100644 (file)
index df8c445..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* GtkAction tests.
- *
- * Authors: Jan Arne Petersen <jpetersen@openismus.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-/* Fixture */
-
-typedef struct
-{
-  GtkAction *action;
-} ActionTest;
-
-static void
-action_test_setup (ActionTest    *fixture,
-                   gconstpointer  test_data)
-{
-  fixture->action = gtk_action_new ("name", "label", NULL, NULL);
-}
-
-static void
-action_test_teardown (ActionTest    *fixture,
-                      gconstpointer  test_data)
-{
-  g_object_unref (fixture->action);
-}
-
-static void
-notify_count_emmisions (GObject    *object,
-                       GParamSpec *pspec,
-                       gpointer    data)
-{
-  unsigned int *i = data;
-  (*i)++;
-}
-
-static void
-menu_item_label_notify_count (ActionTest    *fixture,
-                              gconstpointer  test_data)
-{
-  GtkWidget *item = gtk_menu_item_new ();
-  unsigned int emmisions = 0;
-
-  g_object_ref_sink (item);
-  g_signal_connect (item, "notify::label",
-                   G_CALLBACK (notify_count_emmisions), &emmisions);
-
-  gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item),
-                                        fixture->action);
-
-  g_assert_cmpuint (emmisions, ==, 1);
-
-  gtk_action_set_label (fixture->action, "new label");
-
-  g_assert_cmpuint (emmisions, ==, 2);
-
-  g_object_unref (item);
-}
-
-/* main */
-
-int
-main (int    argc,
-      char **argv)
-{
-  gtk_test_init (&argc, &argv, NULL);
-
-  g_test_add ("/Action/MenuItem/label-notify-count",
-              ActionTest, NULL,
-              action_test_setup,
-              menu_item_label_notify_count,
-              action_test_teardown);
-
-  return g_test_run ();
-}
-
diff --git a/gtk/tests/bitmask.c b/gtk/tests/bitmask.c
deleted file mode 100644 (file)
index 7d186a9..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/* GtkRBTree tests.
- *
- * Copyright (C) 2011, Red Hat, Inc.
- * Authors: Benjamin Otte <otte@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <locale.h>
-
-#include "../../gtk/gtkbitmaskprivate.h"
-
-#include <string.h>
-
-/* how often we run the random tests */
-#define N_RUNS 20
-
-/* how many tries we do in our random tests */
-#define N_TRIES 100
-
-/* the maximum index we use for bitmask values */
-#define MAX_INDEX 1000
-
-/* UTILITIES */
-
-static GtkBitmask *
-gtk_bitmask_new_parse (const char *string)
-{
-  guint i, length;
-  GtkBitmask *mask;
-
-  length = strlen (string);
-  mask = _gtk_bitmask_new ();
-
-  for (i = 0; i < length; i++)
-    {
-      if (string[i] == '0')
-        mask = _gtk_bitmask_set (mask, length - i - 1, FALSE);
-      else if (string[i] == '1')
-        mask = _gtk_bitmask_set (mask, length - i - 1, TRUE);
-      else
-        g_assert_not_reached ();
-    }
-
-  return mask;
-}
-
-#define assert_cmpmasks(mask,other) G_STMT_START { \
-  if (G_UNLIKELY (!_gtk_bitmask_equals (mask, other))) \
-    { \
-      char *mask_string = _gtk_bitmask_to_string (mask); \
-      char *other_string = _gtk_bitmask_to_string (other); \
-      char *msg = g_strdup_printf ("%s (%s) != %s (%s)", \
-                                   G_STRINGIFY (mask), mask_string, \
-                                   G_STRINGIFY (other), other_string); \
-      g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); \
-      g_free (msg); \
-      g_free (mask_string); \
-      g_free (other_string); \
-    } \
-}G_STMT_END
-
-static const char *tests[] = {
-                                                                                                                                   "0",
-                                                                                                                                   "1",
-                                                                                                     "1000000000000000000000000000000",
-                                                                                                    "10000000000000000000000000000000",
-                                                                     "100000000000000000000000000000000000000000000000000000000000000",
-                                                                    "1000000000000000000000000000000000000000000000000000000000000000",
-                                                                   "10000000000000000000000000000000000000000000000000000000000000000",
-  "1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010",
-  "1000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000",
-  "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
-};
-
-static GtkBitmask *masks[G_N_ELEMENTS (tests)];
-
-/* TEST */
-
-static void
-test_to_string (void)
-{
-  guint i;
-  char *to_string;
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++)
-    {
-      to_string = _gtk_bitmask_to_string (masks[i]);
-      g_assert_cmpstr (to_string, ==, tests[i]);
-      g_free (to_string);
-    }
-}
-
-static void
-test_is_empty (void)
-{
-  guint i;
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++)
-    {
-      g_assert_cmpint (_gtk_bitmask_is_empty (masks[i]), ==, i == 0);
-    }
-}
-
-static void
-test_equals (void)
-{
-  guint i, j;
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++)
-    {
-      for (j = 0; j < G_N_ELEMENTS (tests); j++)
-        {
-          g_assert_cmpint (_gtk_bitmask_equals (masks[i], masks[j]), ==, i == j);
-        }
-    }
-}
-
-static void
-test_set (void)
-{
-  guint i, j;
-  guint indexes[N_TRIES];
-  GtkBitmask *copy;
-  const GtkBitmask *mask;
-
-  for (i = 0; i < N_RUNS; i++)
-    {
-      mask = masks[g_test_rand_int_range (0, G_N_ELEMENTS (tests))];
-      copy = _gtk_bitmask_copy (mask);
-
-      for (j = 0; j < N_TRIES; j++)
-        {
-          indexes[j] = g_test_rand_int_range (0, MAX_INDEX);
-          copy = _gtk_bitmask_set (copy, indexes[j], g_test_rand_bit ());
-        }
-
-      for (j = 0; j < N_TRIES; j++)
-        {
-          copy = _gtk_bitmask_set (copy, indexes[j], _gtk_bitmask_get (mask, indexes[j]));
-        }
-
-      assert_cmpmasks (copy, mask);
-      _gtk_bitmask_free (copy);
-    }
-}
-
-static void
-test_union (void)
-{
-  GtkBitmask *left, *right, *expected;
-  guint run, try, n_tries;
-
-  for (run = 0; run < N_RUNS; run++)
-    {
-      left = _gtk_bitmask_new ();
-      right = _gtk_bitmask_new ();
-      expected = _gtk_bitmask_new ();
-
-      n_tries = g_test_perf () ? N_TRIES : g_test_rand_int_range (0, N_TRIES);
-      for (try = 0; try < n_tries; try++)
-        {
-          guint id = g_test_rand_int_range (0, MAX_INDEX);
-
-          if (g_test_rand_bit ())
-            left = _gtk_bitmask_set (left, id, TRUE);
-          else
-            right = _gtk_bitmask_set (right, id, TRUE);
-
-          expected = _gtk_bitmask_set (expected, id, TRUE);
-        }
-
-      left = _gtk_bitmask_union (left, right);
-      right = _gtk_bitmask_union (right, left);
-
-      assert_cmpmasks (left, expected);
-      assert_cmpmasks (right, expected);
-      _gtk_bitmask_free (left);
-      _gtk_bitmask_free (right);
-      _gtk_bitmask_free (expected);
-    }
-}
-
-static void
-test_intersect (void)
-{
-  GtkBitmask *left, *right, *expected;
-  guint run, try;
-  gboolean intersects;
-
-  for (run = 0; run < N_RUNS; run++)
-    {
-      left = _gtk_bitmask_new ();
-      right = _gtk_bitmask_new ();
-      expected = _gtk_bitmask_new ();
-
-      for (try = 0; try < N_TRIES; try++)
-        {
-          guint id = g_test_rand_int_range (0, MAX_INDEX);
-          gboolean set = g_test_rand_bit ();
-
-          if (g_test_rand_bit ())
-            {
-              left = _gtk_bitmask_set (left, id, set);
-              expected = _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (right, id) : 0);
-            }
-          else
-            {
-              right = _gtk_bitmask_set (right, id, set);
-              expected = _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (left, id) : 0);
-            }
-        }
-
-      intersects = _gtk_bitmask_intersects (left, right);
-      g_assert_cmpint (intersects, ==, _gtk_bitmask_intersects (right, left));
-      g_assert_cmpint (intersects, !=, _gtk_bitmask_is_empty (expected));
-
-      left = _gtk_bitmask_intersect (left, right);
-      right = _gtk_bitmask_intersect (right, left);
-
-      assert_cmpmasks (left, expected);
-      assert_cmpmasks (right, expected);
-      _gtk_bitmask_free (left);
-      _gtk_bitmask_free (right);
-      _gtk_bitmask_free (expected);
-    }
-}
-
-static void
-test_intersect_hardcoded (void)
-{
-  GtkBitmask *left, *right, *intersection, *expected;
-  const char *left_str, *right_str;
-  guint left_len, right_len;
-  guint i, l, r;
-
-  for (l = 0; l < G_N_ELEMENTS (tests); l++)
-    {
-      for (r = 0; r < G_N_ELEMENTS (tests); r++)
-        {
-          left = masks[l];
-          right = masks[r];
-          left_str = tests[l];
-          right_str = tests[r];
-          left_len = strlen (tests[l]);
-          right_len = strlen (tests[r]);
-
-          expected = _gtk_bitmask_new ();
-          if (left_len > right_len)
-            left_str += left_len - right_len;
-          if (right_len > left_len)
-            right_str += right_len - left_len;
-          i = MIN (right_len, left_len);
-          while (i--)
-            {
-              expected = _gtk_bitmask_set (expected, i, left_str[0] == '1' && right_str[0] == '1');
-              right_str++;
-              left_str++;
-            }
-
-          intersection = _gtk_bitmask_intersect (_gtk_bitmask_copy (left), right);
-
-          assert_cmpmasks (intersection, expected);
-          g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, !_gtk_bitmask_intersects (left, right));
-
-          _gtk_bitmask_free (intersection);
-          _gtk_bitmask_free (expected);
-        }
-    }
-}
-
-#define SWAP(_a, _b) G_STMT_START{ \
-  guint _tmp = _a; \
-  _a = _b; \
-  _b = _tmp; \
-}G_STMT_END
-
-static void
-test_invert_range (void)
-{
-  GtkBitmask *left, *right, *intersection, *expected;
-  guint run;
-  guint left_start, left_end, right_start, right_end, start, end;
-
-  for (run = 0; run < N_RUNS; run++)
-    {
-      left = _gtk_bitmask_new ();
-      right = _gtk_bitmask_new ();
-      expected = _gtk_bitmask_new ();
-
-      left_start = g_test_rand_int_range (0, MAX_INDEX);
-      left_end = g_test_rand_int_range (0, MAX_INDEX);
-      if (left_start > left_end)
-        SWAP (left_start, left_end);
-      right_start = g_test_rand_int_range (0, MAX_INDEX);
-      right_end = g_test_rand_int_range (0, MAX_INDEX);
-      if (right_start > right_end)
-        SWAP (right_start, right_end);
-      start = MAX (left_start, right_start);
-      end = MIN (left_end, right_end);
-
-      if (left_start != left_end)
-        left = _gtk_bitmask_invert_range (left, left_start, left_end);
-      if (right_start != right_end)
-        right = _gtk_bitmask_invert_range (right, right_start, right_end);
-      if (start < end)
-        expected = _gtk_bitmask_invert_range (expected, start, end);
-
-      intersection = _gtk_bitmask_copy (left);
-      intersection = _gtk_bitmask_intersect (intersection, right);
-
-      assert_cmpmasks (intersection, expected);
-
-      if (start < end)
-        expected = _gtk_bitmask_invert_range (expected, start, end);
-
-      g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, TRUE);
-
-      _gtk_bitmask_free (left);
-      _gtk_bitmask_free (right);
-      _gtk_bitmask_free (intersection);
-      _gtk_bitmask_free (expected);
-    }
-}
-
-/* SETUP & RUNNING */
-
-static void
-create_masks (void)
-{
-  guint i;
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++)
-    masks[i] = gtk_bitmask_new_parse (tests[i]);
-}
-
-static void
-free_masks (void)
-{
-  guint i;
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++)
-    {
-      _gtk_bitmask_free (masks[i]);
-      masks[i] = NULL;
-    }
-}
-
-int
-main (int argc, char *argv[])
-{
-  int result;
-
-  g_test_init (&argc, &argv, NULL);
-  setlocale (LC_ALL, "C");
-  g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
-
-  create_masks ();
-
-  g_test_add_func ("/bitmask/to_string", test_to_string);
-  g_test_add_func ("/bitmask/is_empty", test_is_empty);
-  g_test_add_func ("/bitmask/equals", test_equals);
-  g_test_add_func ("/bitmask/set", test_set);
-  g_test_add_func ("/bitmask/union", test_union);
-  g_test_add_func ("/bitmask/intersect", test_intersect);
-  g_test_add_func ("/bitmask/intersect_hardcoded", test_intersect_hardcoded);
-  g_test_add_func ("/bitmask/invert_range", test_invert_range);
-
-  result = g_test_run ();
-
-  free_masks ();
-
-  return result;
-}
diff --git a/gtk/tests/builder.c b/gtk/tests/builder.c
deleted file mode 100644 (file)
index e924a9a..0000000
+++ /dev/null
@@ -1,2776 +0,0 @@
-/* buildertest.c
- * Copyright (C) 2006-2007 Async Open Source
- * Authors: Johan Dahlin
- *          Henrique Romano
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-#include <libintl.h>
-#include <locale.h>
-#include <math.h>
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-
-/* exported for GtkBuilder */
-void signal_normal (GtkWindow *window, GParamSpec spec);
-void signal_after (GtkWindow *window, GParamSpec spec);
-void signal_object (GtkButton *button, GParamSpec spec);
-void signal_object_after (GtkButton *button, GParamSpec spec);
-void signal_first (GtkButton *button, GParamSpec spec);
-void signal_second (GtkButton *button, GParamSpec spec);
-void signal_extra (GtkButton *button, GParamSpec spec);
-void signal_extra2 (GtkButton *button, GParamSpec spec);
-
-/* Copied from gtkiconfactory.c; keep in sync! */
-struct _GtkIconSet
-{
-  guint ref_count;
-  GSList *sources;
-  GSList *cache;
-  guint cache_size;
-  guint cache_serial;
-};
-
-
-static GtkBuilder *
-builder_new_from_string (const gchar *buffer,
-                         gsize length,
-                         const gchar *domain)
-{
-  GtkBuilder *builder;
-  GError *error = NULL;
-
-  builder = gtk_builder_new ();
-  if (domain)
-    gtk_builder_set_translation_domain (builder, domain);
-  gtk_builder_add_from_string (builder, buffer, length, &error);
-  if (error)
-    {
-      g_print ("ERROR: %s", error->message);
-      g_error_free (error);
-    }
-
-  return builder;
-}
-
-static void
-test_parser (void)
-{
-  GtkBuilder *builder;
-  GError *error;
-  
-  builder = gtk_builder_new ();
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, "<xxx/>", -1, &error);
-  g_assert (g_error_matches (error, 
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_UNHANDLED_TAG));
-  g_error_free (error);
-  
-  error = NULL;
-  gtk_builder_add_from_string (builder, "<interface invalid=\"X\"/>", -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
-  g_error_free (error);
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, "<interface><child/></interface>", -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR, 
-                             GTK_BUILDER_ERROR_INVALID_TAG));
-  g_error_free (error);
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, "<interface><object class=\"GtkVBox\" id=\"a\"><object class=\"GtkHBox\" id=\"b\"/></object></interface>", -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_TAG));
-  g_error_free (error);
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, "<interface><object class=\"Unknown\" id=\"a\"></object></interface>", -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, "<interface><object class=\"GtkWidget\" id=\"a\" constructor=\"none\"></object></interface>", -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, "<interface><object class=\"GtkButton\" id=\"a\"><child internal-child=\"foobar\"><object class=\"GtkButton\" id=\"int\"/></child></object></interface>", -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, "<interface><object class=\"GtkButton\" id=\"a\"></object><object class=\"GtkButton\" id=\"a\"/></object></interface>", -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_DUPLICATE_ID));
-  g_error_free (error);
-
-  g_object_unref (builder);
-}
-
-static int normal = 0;
-static int after = 0;
-static int object = 0;
-static int object_after = 0;
-
-void /* exported for GtkBuilder */
-signal_normal (GtkWindow *window, GParamSpec spec)
-{
-  g_assert (GTK_IS_WINDOW (window));
-  g_assert (normal == 0);
-  g_assert (after == 0);
-
-  normal++;
-}
-
-void /* exported for GtkBuilder */
-signal_after (GtkWindow *window, GParamSpec spec)
-{
-  g_assert (GTK_IS_WINDOW (window));
-  g_assert (normal == 1);
-  g_assert (after == 0);
-  
-  after++;
-}
-
-void /* exported for GtkBuilder */
-signal_object (GtkButton *button, GParamSpec spec)
-{
-  g_assert (GTK_IS_BUTTON (button));
-  g_assert (object == 0);
-  g_assert (object_after == 0);
-
-  object++;
-}
-
-void /* exported for GtkBuilder */
-signal_object_after (GtkButton *button, GParamSpec spec)
-{
-  g_assert (GTK_IS_BUTTON (button));
-  g_assert (object == 1);
-  g_assert (object_after == 0);
-
-  object_after++;
-}
-
-void /* exported for GtkBuilder */
-signal_first (GtkButton *button, GParamSpec spec)
-{
-  g_assert (normal == 0);
-  normal = 10;
-}
-
-void /* exported for GtkBuilder */
-signal_second (GtkButton *button, GParamSpec spec)
-{
-  g_assert (normal == 10);
-  normal = 20;
-}
-
-void /* exported for GtkBuilder */
-signal_extra (GtkButton *button, GParamSpec spec)
-{
-  g_assert (normal == 20);
-  normal = 30;
-}
-
-void /* exported for GtkBuilder */
-signal_extra2 (GtkButton *button, GParamSpec spec)
-{
-  g_assert (normal == 30);
-  normal = 40;
-}
-
-static void
-test_connect_signals (void)
-{
-  GtkBuilder *builder;
-  GObject *window;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkButton\" id=\"button\"/>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <signal name=\"notify::title\" handler=\"signal_normal\"/>"
-    "    <signal name=\"notify::title\" handler=\"signal_after\" after=\"yes\"/>"
-    "    <signal name=\"notify::title\" handler=\"signal_object\""
-    "            object=\"button\"/>"
-    "    <signal name=\"notify::title\" handler=\"signal_object_after\""
-    "            object=\"button\" after=\"yes\"/>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer_order[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <signal name=\"notify::title\" handler=\"signal_first\"/>"
-    "    <signal name=\"notify::title\" handler=\"signal_second\"/>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer_extra[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window2\">"
-    "    <signal name=\"notify::title\" handler=\"signal_extra\"/>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer_extra2[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window3\">"
-    "    <signal name=\"notify::title\" handler=\"signal_extra2\"/>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer_after_child[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkButton\" id=\"button1\"/>"
-    "    </child>"
-    "    <signal name=\"notify::title\" handler=\"signal_normal\"/>"
-    "  </object>"
-    "</interface>";
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  gtk_builder_connect_signals (builder, NULL);
-
-  window = gtk_builder_get_object (builder, "window1");
-  gtk_window_set_title (GTK_WINDOW (window), "test");
-
-  g_assert_cmpint (normal, ==, 1);
-  g_assert_cmpint (after, ==, 1);
-  g_assert_cmpint (object, ==, 1);
-  g_assert_cmpint (object_after, ==, 1);
-
-  gtk_widget_destroy (GTK_WIDGET (window));
-  g_object_unref (builder);
-  
-  builder = builder_new_from_string (buffer_order, -1, NULL);
-  gtk_builder_connect_signals (builder, NULL);
-  window = gtk_builder_get_object (builder, "window1");
-  normal = 0;
-  gtk_window_set_title (GTK_WINDOW (window), "test");
-  g_assert (normal == 20);
-
-  gtk_widget_destroy (GTK_WIDGET (window));
-
-  gtk_builder_add_from_string (builder, buffer_extra,
-                              strlen (buffer_extra), NULL);
-  gtk_builder_add_from_string (builder, buffer_extra2,
-                              strlen (buffer_extra2), NULL);
-  gtk_builder_connect_signals (builder, NULL);
-  window = gtk_builder_get_object (builder, "window2");
-  gtk_window_set_title (GTK_WINDOW (window), "test");
-  g_assert (normal == 30);
-
-  gtk_widget_destroy (GTK_WIDGET (window));
-  window = gtk_builder_get_object (builder, "window3");
-  gtk_window_set_title (GTK_WINDOW (window), "test");
-  g_assert (normal == 40);
-  gtk_widget_destroy (GTK_WIDGET (window));
-  
-  g_object_unref (builder);
-
-  /* new test, reset globals */
-  after = 0;
-  normal = 0;
-  
-  builder = builder_new_from_string (buffer_after_child, -1, NULL);
-  window = gtk_builder_get_object (builder, "window1");
-  gtk_builder_connect_signals (builder, NULL);
-  gtk_window_set_title (GTK_WINDOW (window), "test");
-
-  g_assert (normal == 1);
-  gtk_widget_destroy (GTK_WIDGET (window));
-  g_object_unref (builder);
-}
-
-static void
-test_uimanager_simple (void)
-{
-  GtkBuilder *builder;
-  GObject *window, *uimgr, *menubar;
-  GObject *menu, *label;
-  GList *children;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkUIManager\" id=\"uimgr1\"/>"
-    "</interface>";
-    
-  const gchar buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkUIManager\" id=\"uimgr1\">"
-    "    <child>"
-    "      <object class=\"GtkActionGroup\" id=\"ag1\">"
-    "        <child>"
-    "          <object class=\"GtkAction\" id=\"file\">"
-    "            <property name=\"label\">_File</property>"
-    "          </object>"
-    "          <accelerator key=\"n\" modifiers=\"GDK_CONTROL_MASK\"/>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "    <ui>"
-    "      <menubar name=\"menubar1\">"
-    "        <menu action=\"file\">"
-    "        </menu>"
-    "      </menubar>"
-    "    </ui>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkMenuBar\" id=\"menubar1\" constructor=\"uimgr1\"/>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-
-  uimgr = gtk_builder_get_object (builder, "uimgr1");
-  g_assert (GTK_IS_UI_MANAGER (uimgr));
-  g_object_unref (builder);
-  
-  builder = builder_new_from_string (buffer2, -1, NULL);
-
-  menubar = gtk_builder_get_object (builder, "menubar1");
-  g_assert (GTK_IS_MENU_BAR (menubar));
-
-  children = gtk_container_get_children (GTK_CONTAINER (menubar));
-  menu = children->data;
-  g_assert (GTK_IS_MENU_ITEM (menu));
-  g_assert (strcmp (gtk_widget_get_name (GTK_WIDGET (menu)), "file") == 0);
-  g_list_free (children);
-  
-  label = G_OBJECT (gtk_bin_get_child (GTK_BIN (menu)));
-  g_assert (GTK_IS_LABEL (label));
-  g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
-
-  window = gtk_builder_get_object (builder, "window1");
-  gtk_widget_destroy (GTK_WIDGET (window));
-  g_object_unref (builder);
-}
-
-static void
-test_domain (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer1[] = "<interface/>";
-  const gchar buffer2[] = "<interface domain=\"domain\"/>";
-  const gchar *domain;
-  
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  domain = gtk_builder_get_translation_domain (builder);
-  g_assert (domain == NULL);
-  g_object_unref (builder);
-  
-  builder = builder_new_from_string (buffer1, -1, "domain-1");
-  domain = gtk_builder_get_translation_domain (builder);
-  g_assert (domain);
-  g_assert (strcmp (domain, "domain-1") == 0);
-  g_object_unref (builder);
-
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  domain = gtk_builder_get_translation_domain (builder);
-  g_assert (domain == NULL);
-  g_object_unref (builder);
-}
-
-#if 0
-static void
-test_translation (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkLabel\" id=\"label\">"
-    "        <property name=\"label\" translatable=\"yes\">File</property>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GtkLabel *window, *label;
-
-  setlocale (LC_ALL, "sv_SE");
-  textdomain ("builder");
-  bindtextdomain ("builder", "tests");
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  label = GTK_LABEL (gtk_builder_get_object (builder, "label"));
-  g_assert (strcmp (gtk_label_get_text (label), "Arkiv") == 0);
-
-  window = gtk_builder_get_object (builder, "window1");
-  gtk_widget_destroy (GTK_WIDGET (window));
-  g_object_unref (builder);
-}
-#endif
-
-static void
-test_sizegroup (void)
-{
-  GtkBuilder * builder;
-  const gchar buffer1[] =
-    "<interface domain=\"test\">"
-    "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
-    "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
-    "    <widgets>"
-    "      <widget name=\"radio1\"/>"
-    "      <widget name=\"radio2\"/>"
-    "    </widgets>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkVBox\" id=\"vbox1\">"
-    "        <child>"
-    "          <object class=\"GtkRadioButton\" id=\"radio1\"/>"
-    "        </child>"
-    "        <child>"
-    "          <object class=\"GtkRadioButton\" id=\"radio2\"/>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer2[] =
-    "<interface domain=\"test\">"
-    "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
-    "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
-    "    <widgets>"
-    "    </widgets>"
-    "   </object>"
-    "</interface>";
-  const gchar buffer3[] =
-    "<interface domain=\"test\">"
-    "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
-    "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
-    "    <widgets>"
-    "      <widget name=\"radio1\"/>"
-    "      <widget name=\"radio2\"/>"
-    "    </widgets>"
-    "  </object>"
-    "  <object class=\"GtkSizeGroup\" id=\"sizegroup2\">"
-    "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
-    "    <widgets>"
-    "      <widget name=\"radio1\"/>"
-    "      <widget name=\"radio2\"/>"
-    "    </widgets>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkVBox\" id=\"vbox1\">"
-    "        <child>"
-    "          <object class=\"GtkRadioButton\" id=\"radio1\"/>"
-    "        </child>"
-    "        <child>"
-    "          <object class=\"GtkRadioButton\" id=\"radio2\"/>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GObject *sizegroup;
-  GSList *widgets;
-
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  sizegroup = gtk_builder_get_object (builder, "sizegroup1");
-  widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
-  g_assert (g_slist_length (widgets) == 2);
-  g_slist_free (widgets);
-  g_object_unref (builder);
-
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  sizegroup = gtk_builder_get_object (builder, "sizegroup1");
-  widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
-  g_assert (g_slist_length (widgets) == 0);
-  g_slist_free (widgets);
-  g_object_unref (builder);
-
-  builder = builder_new_from_string (buffer3, -1, NULL);
-  sizegroup = gtk_builder_get_object (builder, "sizegroup1");
-  widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
-  g_assert (g_slist_length (widgets) == 2);
-  g_slist_free (widgets);
-  sizegroup = gtk_builder_get_object (builder, "sizegroup2");
-  widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
-  g_assert (g_slist_length (widgets) == 2);
-  g_slist_free (widgets);
-
-#if 0
-  {
-    GObject *window;
-    window = gtk_builder_get_object (builder, "window1");
-    gtk_widget_destroy (GTK_WIDGET (window));
-  }
-#endif  
-  g_object_unref (builder);
-}
-
-static void
-test_list_store (void)
-{
-  const gchar buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkListStore\" id=\"liststore1\">"
-    "    <columns>"
-    "      <column type=\"gchararray\"/>"
-    "      <column type=\"guint\"/>"
-    "    </columns>"
-    "  </object>"
-    "</interface>";
-  const char buffer2[] = 
-    "<interface>"
-    "  <object class=\"GtkListStore\" id=\"liststore1\">"
-    "    <columns>"
-    "      <column type=\"gchararray\"/>"
-    "      <column type=\"gchararray\"/>"
-    "      <column type=\"gint\"/>"
-    "    </columns>"
-    "    <data>"
-    "      <row>"
-    "        <col id=\"0\" translatable=\"yes\">John</col>"
-    "        <col id=\"1\" context=\"foo\">Doe</col>"
-    "        <col id=\"2\" comment=\"foobar\">25</col>"
-    "      </row>"
-    "      <row>"
-    "        <col id=\"0\">Johan</col>"
-    "        <col id=\"1\">Dole</col>"
-    "        <col id=\"2\">50</col>"
-    "      </row>"
-    "    </data>"
-    "  </object>"
-    "</interface>";
-  const char buffer3[] = 
-    "<interface>"
-    "  <object class=\"GtkListStore\" id=\"liststore1\">"
-    "    <columns>"
-    "      <column type=\"gchararray\"/>"
-    "      <column type=\"gchararray\"/>"
-    "      <column type=\"gint\"/>"
-    "    </columns>"
-    "    <data>"
-    "      <row>"
-    "        <col id=\"1\" context=\"foo\">Doe</col>"
-    "        <col id=\"0\" translatable=\"yes\">John</col>"
-    "        <col id=\"2\" comment=\"foobar\">25</col>"
-    "      </row>"
-    "      <row>"
-    "        <col id=\"2\">50</col>"
-    "        <col id=\"1\">Dole</col>"
-    "        <col id=\"0\">Johan</col>"
-    "      </row>"
-    "      <row>"
-    "        <col id=\"2\">19</col>"
-    "      </row>"
-    "    </data>"
-    "  </object>"
-    "</interface>";
-  GtkBuilder *builder;
-  GObject *store;
-  GtkTreeIter iter;
-  gchar *surname, *lastname;
-  int age;
-  
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  store = gtk_builder_get_object (builder, "liststore1");
-  g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 2);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_UINT);
-  g_object_unref (builder);
-  
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  store = gtk_builder_get_object (builder, "liststore1");
-  g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 3);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_STRING);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2) == G_TYPE_INT);
-  
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter) == TRUE);
-  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
-                      0, &surname,
-                      1, &lastname,
-                      2, &age,
-                      -1);
-  g_assert (surname != NULL);
-  g_assert (strcmp (surname, "John") == 0);
-  g_free (surname);
-  g_assert (lastname != NULL);
-  g_assert (strcmp (lastname, "Doe") == 0);
-  g_free (lastname);
-  g_assert (age == 25);
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
-  
-  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
-                      0, &surname,
-                      1, &lastname,
-                      2, &age,
-                      -1);
-  g_assert (surname != NULL);
-  g_assert (strcmp (surname, "Johan") == 0);
-  g_free (surname);
-  g_assert (lastname != NULL);
-  g_assert (strcmp (lastname, "Dole") == 0);
-  g_free (lastname);
-  g_assert (age == 50);
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == FALSE);
-
-  g_object_unref (builder);  
-
-  builder = builder_new_from_string (buffer3, -1, NULL);
-  store = gtk_builder_get_object (builder, "liststore1");
-  g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 3);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_STRING);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2) == G_TYPE_INT);
-  
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter) == TRUE);
-  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
-                      0, &surname,
-                      1, &lastname,
-                      2, &age,
-                      -1);
-  g_assert (surname != NULL);
-  g_assert (strcmp (surname, "John") == 0);
-  g_free (surname);
-  g_assert (lastname != NULL);
-  g_assert (strcmp (lastname, "Doe") == 0);
-  g_free (lastname);
-  g_assert (age == 25);
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
-  
-  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
-                      0, &surname,
-                      1, &lastname,
-                      2, &age,
-                      -1);
-  g_assert (surname != NULL);
-  g_assert (strcmp (surname, "Johan") == 0);
-  g_free (surname);
-  g_assert (lastname != NULL);
-  g_assert (strcmp (lastname, "Dole") == 0);
-  g_free (lastname);
-  g_assert (age == 50);
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
-  
-  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
-                      0, &surname,
-                      1, &lastname,
-                      2, &age,
-                      -1);
-  g_assert (surname == NULL);
-  g_assert (lastname == NULL);
-  g_assert (age == 19);
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == FALSE);
-
-  g_object_unref (builder);
-}
-
-static void
-test_tree_store (void)
-{
-  const gchar buffer[] =
-    "<interface domain=\"test\">"
-    "  <object class=\"GtkTreeStore\" id=\"treestore1\">"
-    "    <columns>"
-    "      <column type=\"gchararray\"/>"
-    "      <column type=\"guint\"/>"
-    "    </columns>"
-    "  </object>"
-    "</interface>";
-  GtkBuilder *builder;
-  GObject *store;
-  
-  builder = builder_new_from_string (buffer, -1, NULL);
-  store = gtk_builder_get_object (builder, "treestore1");
-  g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 2);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
-  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_UINT);
-  
-  g_object_unref (builder);
-}
-
-static void
-test_types (void)
-{
-  const gchar buffer[] = 
-    "<interface>"
-    "  <object class=\"GtkAction\" id=\"action\"/>"
-    "  <object class=\"GtkActionGroup\" id=\"actiongroup\"/>"
-    "  <object class=\"GtkAlignment\" id=\"alignment\"/>"
-    "  <object class=\"GtkArrow\" id=\"arrow\"/>"
-    "  <object class=\"GtkButton\" id=\"button\"/>"
-    "  <object class=\"GtkCheckButton\" id=\"checkbutton\"/>"
-    "  <object class=\"GtkDialog\" id=\"dialog\"/>"
-    "  <object class=\"GtkDrawingArea\" id=\"drawingarea\"/>"
-    "  <object class=\"GtkEventBox\" id=\"eventbox\"/>"
-    "  <object class=\"GtkEntry\" id=\"entry\"/>"
-    "  <object class=\"GtkFontButton\" id=\"fontbutton\"/>"
-    "  <object class=\"GtkHButtonBox\" id=\"hbuttonbox\"/>"
-    "  <object class=\"GtkHBox\" id=\"hbox\"/>"
-    "  <object class=\"GtkHPaned\" id=\"hpaned\"/>"
-    "  <object class=\"GtkHScale\" id=\"hscale\"/>"
-    "  <object class=\"GtkHScrollbar\" id=\"hscrollbar\"/>"
-    "  <object class=\"GtkHSeparator\" id=\"hseparator\"/>"
-    "  <object class=\"GtkImage\" id=\"image\"/>"
-    "  <object class=\"GtkLabel\" id=\"label\"/>"
-    "  <object class=\"GtkListStore\" id=\"liststore\"/>"
-    "  <object class=\"GtkMenuBar\" id=\"menubar\"/>"
-    "  <object class=\"GtkNotebook\" id=\"notebook\"/>"
-    "  <object class=\"GtkProgressBar\" id=\"progressbar\"/>"
-    "  <object class=\"GtkRadioButton\" id=\"radiobutton\"/>"
-    "  <object class=\"GtkSizeGroup\" id=\"sizegroup\"/>"
-    "  <object class=\"GtkScrolledWindow\" id=\"scrolledwindow\"/>"
-    "  <object class=\"GtkSpinButton\" id=\"spinbutton\"/>"
-    "  <object class=\"GtkStatusbar\" id=\"statusbar\"/>"
-    "  <object class=\"GtkTextView\" id=\"textview\"/>"
-    "  <object class=\"GtkToggleAction\" id=\"toggleaction\"/>"
-    "  <object class=\"GtkToggleButton\" id=\"togglebutton\"/>"
-    "  <object class=\"GtkToolbar\" id=\"toolbar\"/>"
-    "  <object class=\"GtkTreeStore\" id=\"treestore\"/>"
-    "  <object class=\"GtkTreeView\" id=\"treeview\"/>"
-    "  <object class=\"GtkTable\" id=\"table\"/>"
-    "  <object class=\"GtkVBox\" id=\"vbox\"/>"
-    "  <object class=\"GtkVButtonBox\" id=\"vbuttonbox\"/>"
-    "  <object class=\"GtkVScrollbar\" id=\"vscrollbar\"/>"
-    "  <object class=\"GtkVSeparator\" id=\"vseparator\"/>"
-    "  <object class=\"GtkViewport\" id=\"viewport\"/>"
-    "  <object class=\"GtkVPaned\" id=\"vpaned\"/>"
-    "  <object class=\"GtkVScale\" id=\"vscale\"/>"
-    "  <object class=\"GtkWindow\" id=\"window\"/>"
-    "  <object class=\"GtkUIManager\" id=\"uimanager\"/>"
-    "</interface>";
-  const gchar buffer2[] = 
-    "<interface>"
-    "  <object type-func=\"gtk_window_get_type\" id=\"window\"/>"
-    "</interface>";
-  const gchar buffer3[] = 
-    "<interface>"
-    "  <object type-func=\"xxx_invalid_get_type_function\" id=\"window\"/>"
-    "</interface>";
-  GtkBuilder *builder;
-  GObject *window;
-  GError *error;
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "dialog")));
-  gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "window")));
-  g_object_unref (builder);
-
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  window = gtk_builder_get_object (builder, "window");
-  g_assert (GTK_IS_WINDOW (window));
-  gtk_widget_destroy (GTK_WIDGET (window));
-  g_object_unref (builder);
-  
-  error = NULL;
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_string (builder, buffer3, -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION));
-  g_error_free (error);
-  g_object_unref (builder);
-}
-
-static void
-test_spin_button (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "<object class=\"GtkAdjustment\" id=\"adjustment1\">"
-    "<property name=\"lower\">0</property>"
-    "<property name=\"upper\">10</property>"
-    "<property name=\"step-increment\">2</property>"
-    "<property name=\"page-increment\">3</property>"
-    "<property name=\"page-size\">0</property>"
-    "<property name=\"value\">1</property>"
-    "</object>"
-    "<object class=\"GtkSpinButton\" id=\"spinbutton1\">"
-    "<property name=\"visible\">True</property>"
-    "<property name=\"adjustment\">adjustment1</property>"
-    "</object>"
-    "</interface>";
-  GObject *obj;
-  GtkAdjustment *adjustment;
-  gdouble value;
-  
-  builder = builder_new_from_string (buffer, -1, NULL);
-  obj = gtk_builder_get_object (builder, "spinbutton1");
-  g_assert (GTK_IS_SPIN_BUTTON (obj));
-  adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (obj));
-  g_assert (GTK_IS_ADJUSTMENT (adjustment));
-  g_object_get (adjustment, "value", &value, NULL);
-  g_assert (value == 1);
-  g_object_get (adjustment, "lower", &value, NULL);
-  g_assert (value == 0);
-  g_object_get (adjustment, "upper", &value, NULL);
-  g_assert (value == 10);
-  g_object_get (adjustment, "step-increment", &value, NULL);
-  g_assert (value == 2);
-  g_object_get (adjustment, "page-increment", &value, NULL);
-  g_assert (value == 3);
-  g_object_get (adjustment, "page-size", &value, NULL);
-  g_assert (value == 0);
-  
-  g_object_unref (builder);
-}
-
-static void
-test_notebook (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkNotebook\" id=\"notebook1\">"
-    "    <child>"
-    "      <object class=\"GtkLabel\" id=\"label1\">"
-    "        <property name=\"label\">label1</property>"
-    "      </object>"
-    "    </child>"
-    "    <child type=\"tab\">"
-    "      <object class=\"GtkLabel\" id=\"tablabel1\">"
-    "        <property name=\"label\">tab_label1</property>"
-    "      </object>"
-    "    </child>"
-    "    <child>"
-    "      <object class=\"GtkLabel\" id=\"label2\">"
-    "        <property name=\"label\">label2</property>"
-    "      </object>"
-    "    </child>"
-    "    <child type=\"tab\">"
-    "      <object class=\"GtkLabel\" id=\"tablabel2\">"
-    "        <property name=\"label\">tab_label2</property>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GObject *notebook;
-  GtkWidget *label;
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  notebook = gtk_builder_get_object (builder, "notebook1");
-  g_assert (notebook != NULL);
-  g_assert (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) == 2);
-
-  label = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0);
-  g_assert (GTK_IS_LABEL (label));
-  g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "label1") == 0);
-  label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), label);
-  g_assert (GTK_IS_LABEL (label));
-  g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "tab_label1") == 0);
-
-  label = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1);
-  g_assert (GTK_IS_LABEL (label));
-  g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "label2") == 0);
-  label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), label);
-  g_assert (GTK_IS_LABEL (label));
-  g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "tab_label2") == 0);
-
-  g_object_unref (builder);
-}
-
-static void
-test_construct_only_property (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <property name=\"type\">GTK_WINDOW_POPUP</property>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkTextTagTable\" id=\"tagtable1\"/>"
-    "  <object class=\"GtkTextBuffer\" id=\"textbuffer1\">"
-    "    <property name=\"tag-table\">tagtable1</property>"
-    "  </object>"
-    "</interface>";
-  GObject *widget, *tagtable, *textbuffer;
-  GtkWindowType type;
-  
-  builder = builder_new_from_string (buffer, -1, NULL);
-  widget = gtk_builder_get_object (builder, "window1");
-  g_object_get (widget, "type", &type, NULL);
-  g_assert (type == GTK_WINDOW_POPUP);
-
-  gtk_widget_destroy (GTK_WIDGET (widget));
-  g_object_unref (builder);
-
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  textbuffer = gtk_builder_get_object (builder, "textbuffer1");
-  g_assert (textbuffer != NULL);
-  g_object_get (textbuffer, "tag-table", &tagtable, NULL);
-  g_assert (tagtable == gtk_builder_get_object (builder, "tagtable1"));
-  g_object_unref (tagtable);
-  g_object_unref (builder);
-}
-
-static void
-test_object_properties (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkVBox\" id=\"vbox\">"
-    "        <property name=\"border-width\">10</property>"
-    "        <child>"
-    "          <object class=\"GtkLabel\" id=\"label1\">"
-    "            <property name=\"mnemonic-widget\">spinbutton1</property>"
-    "          </object>"
-    "        </child>"
-    "        <child>"
-    "          <object class=\"GtkSpinButton\" id=\"spinbutton1\"/>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window2\"/>"
-    "</interface>";
-  GObject *label, *spinbutton, *window;
-  
-  builder = builder_new_from_string (buffer, -1, NULL);
-  label = gtk_builder_get_object (builder, "label1");
-  g_assert (label != NULL);
-  spinbutton = gtk_builder_get_object (builder, "spinbutton1");
-  g_assert (spinbutton != NULL);
-  g_assert (spinbutton == (GObject*)gtk_label_get_mnemonic_widget (GTK_LABEL (label)));
-
-  gtk_builder_add_from_string (builder, buffer2, -1, NULL);
-  window = gtk_builder_get_object (builder, "window2");
-  g_assert (window != NULL);
-  gtk_widget_destroy (GTK_WIDGET (window));
-
-  g_object_unref (builder);
-}
-
-static void
-test_children (void)
-{
-  GtkBuilder * builder;
-  GtkWidget *content_area, *dialog_action_area;
-  GList *children;
-  const gchar buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkButton\" id=\"button1\">"
-    "        <property name=\"label\">Hello</property>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkDialog\" id=\"dialog1\">"
-    "    <child internal-child=\"vbox\">"
-    "      <object class=\"GtkVBox\" id=\"dialog1-vbox\">"
-    "        <property name=\"border-width\">10</property>"
-    "          <child internal-child=\"action_area\">"
-    "            <object class=\"GtkHButtonBox\" id=\"dialog1-action_area\">"
-    "              <property name=\"border-width\">20</property>"
-    "            </object>"
-    "          </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-
-  GObject *window, *button;
-  GObject *dialog, *vbox, *action_area;
-  
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  window = gtk_builder_get_object (builder, "window1");
-  g_assert (window != NULL);
-  g_assert (GTK_IS_WINDOW (window));
-
-  button = gtk_builder_get_object (builder, "button1");
-  g_assert (button != NULL);
-  g_assert (GTK_IS_BUTTON (button));
-  g_assert (gtk_widget_get_parent (GTK_WIDGET(button)) != NULL);
-  g_assert (strcmp (gtk_buildable_get_name (GTK_BUILDABLE (gtk_widget_get_parent (GTK_WIDGET (button)))), "window1") == 0);
-
-  gtk_widget_destroy (GTK_WIDGET (window));
-  g_object_unref (builder);
-  
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  dialog = gtk_builder_get_object (builder, "dialog1");
-  g_assert (dialog != NULL);
-  g_assert (GTK_IS_DIALOG (dialog));
-  children = gtk_container_get_children (GTK_CONTAINER (dialog));
-  g_assert (g_list_length (children) == 1);
-  g_list_free (children);
-  
-  vbox = gtk_builder_get_object (builder, "dialog1-vbox");
-  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
-  g_assert (vbox != NULL);
-  g_assert (GTK_IS_BOX (vbox));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (vbox)) == GTK_ORIENTATION_VERTICAL);
-  g_assert (strcmp (gtk_buildable_get_name (GTK_BUILDABLE (gtk_widget_get_parent (GTK_WIDGET (vbox)))), "dialog1") == 0);
-  g_assert (gtk_container_get_border_width (GTK_CONTAINER (vbox)) == 10);
-  g_assert (strcmp (gtk_buildable_get_name (GTK_BUILDABLE (content_area)), "dialog1-vbox") == 0);
-
-  action_area = gtk_builder_get_object (builder, "dialog1-action_area");
-  dialog_action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
-  g_assert (action_area != NULL);
-  g_assert (GTK_IS_BUTTON_BOX (action_area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (action_area)) == GTK_ORIENTATION_HORIZONTAL);
-  g_assert (gtk_widget_get_parent (GTK_WIDGET (action_area)) != NULL);
-  g_assert (gtk_container_get_border_width (GTK_CONTAINER (action_area)) == 20);
-  g_assert (dialog_action_area != NULL);
-  g_assert (gtk_buildable_get_name (GTK_BUILDABLE (action_area)) != NULL);
-  g_assert (strcmp (gtk_buildable_get_name (GTK_BUILDABLE (dialog_action_area)), "dialog1-action_area") == 0);
-  gtk_widget_destroy (GTK_WIDGET (dialog));
-  g_object_unref (builder);
-}
-
-static void
-test_child_properties (void)
-{
-  GtkBuilder * builder;
-  const gchar buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkBox\" id=\"vbox1\">"
-    "    <child>"
-    "      <object class=\"GtkLabel\" id=\"label1\"/>"
-    "      <packing>"
-    "        <property name=\"pack-type\">start</property>"
-    "      </packing>"
-    "    </child>"
-    "    <child>"
-    "      <object class=\"GtkLabel\" id=\"label2\"/>"
-    "      <packing>"
-    "        <property name=\"pack-type\">end</property>"
-    "      </packing>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-
-  GObject *label, *vbox;
-  GtkPackType pack_type;
-  
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  vbox = gtk_builder_get_object (builder, "vbox1");
-  g_assert (GTK_IS_BOX (vbox));
-
-  label = gtk_builder_get_object (builder, "label1");
-  g_assert (GTK_IS_LABEL (label));
-  gtk_container_child_get (GTK_CONTAINER (vbox),
-                           GTK_WIDGET (label),
-                           "pack-type",
-                           &pack_type,
-                           NULL);
-  g_assert (pack_type == GTK_PACK_START);
-  
-  label = gtk_builder_get_object (builder, "label2");
-  g_assert (GTK_IS_LABEL (label));
-  gtk_container_child_get (GTK_CONTAINER (vbox),
-                           GTK_WIDGET (label),
-                           "pack-type",
-                           &pack_type,
-                           NULL);
-  g_assert (pack_type == GTK_PACK_END);
-
-  g_object_unref (builder);
-}
-
-static void
-test_treeview_column (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "<object class=\"GtkListStore\" id=\"liststore1\">"
-    "  <columns>"
-    "    <column type=\"gchararray\"/>"
-    "    <column type=\"guint\"/>"
-    "  </columns>"
-    "  <data>"
-    "    <row>"
-    "      <col id=\"0\">John</col>"
-    "      <col id=\"1\">25</col>"
-    "    </row>"
-    "  </data>"
-    "</object>"
-    "<object class=\"GtkWindow\" id=\"window1\">"
-    "  <child>"
-    "    <object class=\"GtkTreeView\" id=\"treeview1\">"
-    "      <property name=\"visible\">True</property>"
-    "      <property name=\"model\">liststore1</property>"
-    "      <child>"
-    "        <object class=\"GtkTreeViewColumn\" id=\"column1\">"
-    "          <property name=\"title\">Test</property>"
-    "          <child>"
-    "            <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
-    "            <attributes>"
-    "              <attribute name=\"text\">1</attribute>"
-    "            </attributes>"
-    "          </child>"
-    "        </object>"
-    "      </child>"
-    "      <child>"
-    "        <object class=\"GtkTreeViewColumn\" id=\"column2\">"
-    "          <property name=\"title\">Number</property>"
-    "          <child>"
-    "            <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
-    "            <attributes>"
-    "              <attribute name=\"text\">0</attribute>"
-    "            </attributes>"
-    "          </child>"
-    "        </object>"
-    "      </child>"
-    "    </object>"
-    "  </child>"
-    "</object>"
-    "</interface>";
-  GObject *window, *treeview;
-  GtkTreeViewColumn *column;
-  GList *renderers;
-  GObject *renderer;
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  treeview = gtk_builder_get_object (builder, "treeview1");
-  g_assert (treeview);
-  g_assert (GTK_IS_TREE_VIEW (treeview));
-  column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 0);
-  g_assert (GTK_IS_TREE_VIEW_COLUMN (column));
-  g_assert (strcmp (gtk_tree_view_column_get_title (column), "Test") == 0);
-
-  renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
-  g_assert (g_list_length (renderers) == 1);
-  renderer = g_list_nth_data (renderers, 0);
-  g_assert (renderer);
-  g_assert (GTK_IS_CELL_RENDERER_TEXT (renderer));
-  g_list_free (renderers);
-
-  window = gtk_builder_get_object (builder, "window1");
-  gtk_widget_destroy (GTK_WIDGET (window));
-
-  g_object_unref (builder);
-}
-
-static void
-test_icon_view (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkListStore\" id=\"liststore1\">"
-    "    <columns>"
-    "      <column type=\"gchararray\"/>"
-    "      <column type=\"GdkPixbuf\"/>"
-    "    </columns>"
-    "    <data>"
-    "      <row>"
-    "        <col id=\"0\">test</col>"
-    "      </row>"
-    "    </data>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkIconView\" id=\"iconview1\">"
-    "        <property name=\"model\">liststore1</property>"
-    "        <property name=\"text-column\">0</property>"
-    "        <property name=\"pixbuf-column\">1</property>"
-    "        <property name=\"visible\">True</property>"
-    "        <child>"
-    "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
-    "          <attributes>"
-    "            <attribute name=\"text\">0</attribute>"
-    "          </attributes>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GObject *window, *iconview;
-  
-  builder = builder_new_from_string (buffer, -1, NULL);
-  iconview = gtk_builder_get_object (builder, "iconview1");
-  g_assert (iconview);
-  g_assert (GTK_IS_ICON_VIEW (iconview));
-
-  window = gtk_builder_get_object (builder, "window1");
-  gtk_widget_destroy (GTK_WIDGET (window));
-  g_object_unref (builder);
-}
-
-static void
-test_combo_box (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkListStore\" id=\"liststore1\">"
-    "    <columns>"
-    "      <column type=\"guint\"/>"
-    "      <column type=\"gchararray\"/>"
-    "    </columns>"
-    "    <data>"
-    "      <row>"
-    "        <col id=\"0\">1</col>"
-    "        <col id=\"1\">Foo</col>"
-    "      </row>"
-    "      <row>"
-    "        <col id=\"0\">2</col>"
-    "        <col id=\"1\">Bar</col>"
-    "      </row>"
-    "    </data>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkComboBox\" id=\"combobox1\">"
-    "        <property name=\"model\">liststore1</property>"
-    "        <property name=\"visible\">True</property>"
-    "        <child>"
-    "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
-    "          <attributes>"
-    "            <attribute name=\"text\">0</attribute>"
-    "          </attributes>"
-    "        </child>"
-    "        <child>"
-    "          <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
-    "          <attributes>"
-    "            <attribute name=\"text\">1</attribute>"
-    "          </attributes>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GObject *window, *combobox;
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  combobox = gtk_builder_get_object (builder, "combobox1");
-  g_assert (combobox);
-
-  window = gtk_builder_get_object (builder, "window1");
-  gtk_widget_destroy (GTK_WIDGET (window));
-
-  g_object_unref (builder);
-}
-
-#if 0
-static void
-test_combo_box_entry (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkListStore\" id=\"liststore1\">"
-    "    <columns>"
-    "      <column type=\"guint\"/>"
-    "      <column type=\"gchararray\"/>"
-    "    </columns>"
-    "    <data>"
-    "      <row>"
-    "        <col id=\"0\">1</col>"
-    "        <col id=\"1\">Foo</col>"
-    "      </row>"
-    "      <row>"
-    "        <col id=\"0\">2</col>"
-    "        <col id=\"1\">Bar</col>"
-    "      </row>"
-    "    </data>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkComboBox\" id=\"comboboxentry1\">"
-    "        <property name=\"model\">liststore1</property>"
-    "        <property name=\"has-entry\">True</property>"
-    "        <property name=\"visible\">True</property>"
-    "        <child>"
-    "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
-    "            <attributes>"
-    "              <attribute name=\"text\">0</attribute>"
-    "            </attributes>"
-    "        </child>"
-    "        <child>"
-    "          <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
-    "            <attributes>"
-    "              <attribute name=\"text\">1</attribute>"
-    "            </attributes>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GObject *window, *combobox, *renderer;
-  gchar *text;
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  combobox = gtk_builder_get_object (builder, "comboboxentry1");
-  g_assert (combobox);
-
-  renderer = gtk_builder_get_object (builder, "renderer2");
-  g_assert (renderer);
-  g_object_get (renderer, "text", &text, NULL);
-  g_assert (text);
-  g_assert (strcmp (text, "Bar") == 0);
-  g_free (text);
-
-  renderer = gtk_builder_get_object (builder, "renderer1");
-  g_assert (renderer);
-  g_object_get (renderer, "text", &text, NULL);
-  g_assert (text);
-  g_assert (strcmp (text, "2") == 0);
-  g_free (text);
-
-  window = gtk_builder_get_object (builder, "window1");
-  gtk_widget_destroy (GTK_WIDGET (window));
-
-  g_object_unref (builder);
-}
-#endif
-
-static void
-test_cell_view (void)
-{
-  GtkBuilder *builder;
-  const gchar *buffer =
-    "<interface>"
-    "  <object class=\"GtkListStore\" id=\"liststore1\">"
-    "    <columns>"
-    "      <column type=\"gchararray\"/>"
-    "    </columns>"
-    "    <data>"
-    "      <row>"
-    "        <col id=\"0\">test</col>"
-    "      </row>"
-    "    </data>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkCellView\" id=\"cellview1\">"
-    "        <property name=\"visible\">True</property>"
-    "        <property name=\"model\">liststore1</property>"
-    "        <accelerator key=\"f\" modifiers=\"GDK_CONTROL_MASK\" signal=\"grab_focus\"/>"
-    "        <child>"
-    "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
-    "          <attributes>"
-    "            <attribute name=\"text\">0</attribute>"
-    "          </attributes>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GObject *cellview;
-  GObject *model, *window;
-  GtkTreePath *path;
-  GList *renderers;
-  
-  builder = builder_new_from_string (buffer, -1, NULL);
-  cellview = gtk_builder_get_object (builder, "cellview1");
-  g_assert (builder);
-  g_assert (cellview);
-  g_assert (GTK_IS_CELL_VIEW (cellview));
-  g_object_get (cellview, "model", &model, NULL);
-  g_assert (model);
-  g_assert (GTK_IS_TREE_MODEL (model));
-  g_object_unref (model);
-  path = gtk_tree_path_new_first ();
-  gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (cellview), path);
-  
-  renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cellview));
-  g_assert (renderers);
-  g_assert (g_list_length (renderers) == 1);
-
-  window = gtk_builder_get_object (builder, "window1");
-  g_assert (window);
-  gtk_widget_destroy (GTK_WIDGET (window));
-  
-  g_object_unref (builder);
-}
-
-static void
-test_dialog (void)
-{
-  GtkBuilder * builder;
-  const gchar buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkDialog\" id=\"dialog1\">"
-    "    <child internal-child=\"vbox\">"
-    "      <object class=\"GtkVBox\" id=\"dialog1-vbox\">"
-    "          <child internal-child=\"action_area\">"
-    "            <object class=\"GtkHButtonBox\" id=\"dialog1-action_area\">"
-    "              <child>"
-    "                <object class=\"GtkButton\" id=\"button_cancel\"/>"
-    "              </child>"
-    "              <child>"
-    "                <object class=\"GtkButton\" id=\"button_ok\"/>"
-    "              </child>"
-    "            </object>"
-    "          </child>"
-    "      </object>"
-    "    </child>"
-    "    <action-widgets>"
-    "      <action-widget response=\"3\">button_ok</action-widget>"
-    "      <action-widget response=\"-5\">button_cancel</action-widget>"
-    "    </action-widgets>"
-    "  </object>"
-    "</interface>";
-
-  GObject *dialog1;
-  GObject *button_ok;
-  GObject *button_cancel;
-  
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  dialog1 = gtk_builder_get_object (builder, "dialog1");
-  button_ok = gtk_builder_get_object (builder, "button_ok");
-  g_assert (gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog1), GTK_WIDGET (button_ok)) == 3);
-  button_cancel = gtk_builder_get_object (builder, "button_cancel");
-  g_assert (gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog1), GTK_WIDGET (button_cancel)) == -5);
-  
-  gtk_widget_destroy (GTK_WIDGET (dialog1));
-  g_object_unref (builder);
-}
-
-static void
-test_message_dialog (void)
-{
-  GtkBuilder * builder;
-  const gchar buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkMessageDialog\" id=\"dialog1\">"
-    "    <child internal-child=\"message_area\">"
-    "      <object class=\"GtkVBox\" id=\"dialog-message-area\">"
-    "        <child>"
-    "          <object class=\"GtkExpander\" id=\"expander\"/>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-
-  GObject *dialog1;
-  GObject *expander;
-
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  dialog1 = gtk_builder_get_object (builder, "dialog1");
-  expander = gtk_builder_get_object (builder, "expander");
-  g_assert (GTK_IS_EXPANDER (expander));
-  g_assert (gtk_widget_get_parent (GTK_WIDGET (expander)) == gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog1)));
-
-  gtk_widget_destroy (GTK_WIDGET (dialog1));
-  g_object_unref (builder);
-}
-
-static void
-test_accelerators (void)
-{
-  GtkBuilder *builder;
-  const gchar *buffer =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkButton\" id=\"button1\">"
-    "        <accelerator key=\"q\" modifiers=\"GDK_CONTROL_MASK\" signal=\"clicked\"/>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  const gchar *buffer2 =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkTreeView\" id=\"treeview1\">"
-    "        <signal name=\"cursor-changed\" handler=\"gtk_main_quit\"/>"
-    "        <accelerator key=\"f\" modifiers=\"GDK_CONTROL_MASK\" signal=\"grab_focus\"/>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GObject *window1;
-  GSList *accel_groups;
-  GObject *accel_group;
-  
-  builder = builder_new_from_string (buffer, -1, NULL);
-  window1 = gtk_builder_get_object (builder, "window1");
-  g_assert (window1);
-  g_assert (GTK_IS_WINDOW (window1));
-
-  accel_groups = gtk_accel_groups_from_object (window1);
-  g_assert (g_slist_length (accel_groups) == 1);
-  accel_group = g_slist_nth_data (accel_groups, 0);
-  g_assert (accel_group);
-
-  gtk_widget_destroy (GTK_WIDGET (window1));
-  g_object_unref (builder);
-
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  window1 = gtk_builder_get_object (builder, "window1");
-  g_assert (window1);
-  g_assert (GTK_IS_WINDOW (window1));
-
-  accel_groups = gtk_accel_groups_from_object (window1);
-  g_assert (g_slist_length (accel_groups) == 1);
-  accel_group = g_slist_nth_data (accel_groups, 0);
-  g_assert (accel_group);
-
-  gtk_widget_destroy (GTK_WIDGET (window1));
-  g_object_unref (builder);
-}
-
-static void
-test_widget (void)
-{
-  const gchar *buffer =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkButton\" id=\"button1\">"
-    "         <property name=\"can-focus\">True</property>"
-    "         <property name=\"has-focus\">True</property>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-   "</interface>";
-  const gchar *buffer2 =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkButton\" id=\"button1\">"
-    "         <property name=\"can-default\">True</property>"
-    "         <property name=\"has-default\">True</property>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-   "</interface>";
-  const gchar *buffer3 =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkVBox\" id=\"vbox1\">"
-    "        <child>"
-    "          <object class=\"GtkLabel\" id=\"label1\">"
-    "            <child internal-child=\"accessible\">"
-    "              <object class=\"AtkObject\" id=\"a11y-label1\">"
-    "                <property name=\"AtkObject::accessible-name\">A Label</property>"
-    "              </object>"
-    "            </child>"
-    "            <accessibility>"
-    "              <relation target=\"button1\" type=\"label-for\"/>"
-    "            </accessibility>"
-    "          </object>"
-    "        </child>"
-    "        <child>"
-    "          <object class=\"GtkButton\" id=\"button1\">"
-    "            <accessibility>"
-    "              <action action_name=\"click\" description=\"Sliff\"/>"
-    "              <action action_name=\"clack\" translatable=\"yes\">Sniff</action>"
-    "            </accessibility>"
-    "          </object>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GtkBuilder *builder;
-  GObject *window1, *button1, *label1;
-  AtkObject *accessible;
-  AtkRelationSet *relation_set;
-  AtkRelation *relation;
-  char *name;
-  
-  builder = builder_new_from_string (buffer, -1, NULL);
-  button1 = gtk_builder_get_object (builder, "button1");
-
-#if 0
-  g_assert (gtk_widget_has_focus (GTK_WIDGET (button1)));
-#endif
-  window1 = gtk_builder_get_object (builder, "window1");
-  gtk_widget_destroy (GTK_WIDGET (window1));
-  
-  g_object_unref (builder);
-  
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  button1 = gtk_builder_get_object (builder, "button1");
-
-  g_assert (gtk_widget_get_receives_default (GTK_WIDGET (button1)));
-  
-  g_object_unref (builder);
-  
-  builder = builder_new_from_string (buffer3, -1, NULL);
-
-  window1 = gtk_builder_get_object (builder, "window1");
-  label1 = gtk_builder_get_object (builder, "label1");
-
-  accessible = gtk_widget_get_accessible (GTK_WIDGET (label1));
-  relation_set = atk_object_ref_relation_set (accessible);
-  g_return_if_fail (atk_relation_set_get_n_relations (relation_set) == 1);
-  relation = atk_relation_set_get_relation (relation_set, 0);
-  g_return_if_fail (relation != NULL);
-  g_return_if_fail (ATK_IS_RELATION (relation));
-  g_return_if_fail (atk_relation_get_relation_type (relation) != ATK_RELATION_LABELLED_BY);
-  g_object_unref (relation_set);
-
-  g_object_get (G_OBJECT (accessible), "accessible-name", &name, NULL);
-  g_return_if_fail (strcmp (name, "A Label") == 0);
-  g_free (name);
-  
-  gtk_widget_destroy (GTK_WIDGET (window1));
-  g_object_unref (builder);
-}
-
-static void
-test_window (void)
-{
-  const gchar *buffer1 =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "     <property name=\"title\"></property>"
-    "  </object>"
-   "</interface>";
-  const gchar *buffer2 =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "  </object>"
-   "</interface>";
-  GtkBuilder *builder;
-  GObject *window1;
-  gchar *title;
-  
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  window1 = gtk_builder_get_object (builder, "window1");
-  g_object_get (window1, "title", &title, NULL);
-  g_assert (strcmp (title, "") == 0);
-  g_free (title);
-  gtk_widget_destroy (GTK_WIDGET (window1));
-  g_object_unref (builder);
-
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  window1 = gtk_builder_get_object (builder, "window1");
-  gtk_widget_destroy (GTK_WIDGET (window1));
-  g_object_unref (builder);
-}
-
-static void
-test_value_from_string (void)
-{
-  GValue value = G_VALUE_INIT;
-  GError *error = NULL;
-  GtkBuilder *builder;
-
-  builder = gtk_builder_new ();
-  
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_STRING, "test", &value, &error));
-  g_assert (G_VALUE_HOLDS_STRING (&value));
-  g_assert (strcmp (g_value_get_string (&value), "test") == 0);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "true", &value, &error));
-  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
-  g_assert (g_value_get_boolean (&value) == TRUE);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "false", &value, &error));
-  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
-  g_assert (g_value_get_boolean (&value) == FALSE);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yes", &value, &error));
-  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
-  g_assert (g_value_get_boolean (&value) == TRUE);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "no", &value, &error));
-  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
-  g_assert (g_value_get_boolean (&value) == FALSE);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "0", &value, &error));
-  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
-  g_assert (g_value_get_boolean (&value) == FALSE);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "1", &value, &error));
-  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
-  g_assert (g_value_get_boolean (&value) == TRUE);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "tRuE", &value, &error));
-  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
-  g_assert (g_value_get_boolean (&value) == TRUE);
-  g_value_unset (&value);
-  
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "blaurgh", &value, &error) == FALSE);
-  g_value_unset (&value);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-  error = NULL;
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yess", &value, &error) == FALSE);
-  g_value_unset (&value);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-  error = NULL;
-  
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "trueee", &value, &error) == FALSE);
-  g_value_unset (&value);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-  error = NULL;
-  
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "", &value, &error) == FALSE);
-  g_value_unset (&value);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-  error = NULL;
-  
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "12345", &value, &error));
-  g_assert (G_VALUE_HOLDS_INT (&value));
-  g_assert (g_value_get_int (&value) == 12345);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_LONG, "9912345", &value, &error));
-  g_assert (G_VALUE_HOLDS_LONG (&value));
-  g_assert (g_value_get_long (&value) == 9912345);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_UINT, "2345", &value, &error));
-  g_assert (G_VALUE_HOLDS_UINT (&value));
-  g_assert (g_value_get_uint (&value) == 2345);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_FLOAT, "1.454", &value, &error));
-  g_assert (G_VALUE_HOLDS_FLOAT (&value));
-  g_assert (fabs (g_value_get_float (&value) - 1.454) < 0.00001);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_FLOAT, "abc", &value, &error) == FALSE);
-  g_value_unset (&value);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-  error = NULL;
-
-  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "/-+,abc", &value, &error) == FALSE);
-  g_value_unset (&value);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-  error = NULL;
-
-  g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "toplevel", &value, &error) == TRUE);
-  g_assert (G_VALUE_HOLDS_ENUM (&value));
-  g_assert (g_value_get_enum (&value) == GTK_WINDOW_TOPLEVEL);
-  g_value_unset (&value);
-
-  g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "sliff", &value, &error) == FALSE);
-  g_value_unset (&value);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-  error = NULL;
-
-  g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "foobar", &value, &error) == FALSE);
-  g_value_unset (&value);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_VALUE));
-  g_error_free (error);
-  error = NULL;
-  
-  g_object_unref (builder);
-}
-
-static gboolean model_freed = FALSE;
-
-static void
-model_weakref (gpointer data,
-               GObject *model)
-{
-  model_freed = TRUE;
-}
-
-static void
-test_reference_counting (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkListStore\" id=\"liststore1\"/>"
-    "  <object class=\"GtkListStore\" id=\"liststore2\"/>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkTreeView\" id=\"treeview1\">"
-    "        <property name=\"model\">liststore1</property>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkVBox\" id=\"vbox1\">"
-    "    <child>"
-    "      <object class=\"GtkLabel\" id=\"label1\"/>"
-    "      <packing>"
-    "        <property name=\"pack-type\">start</property>"
-    "      </packing>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  GObject *window, *treeview, *model;
-  
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  window = gtk_builder_get_object (builder, "window1");
-  treeview = gtk_builder_get_object (builder, "treeview1");
-  model = gtk_builder_get_object (builder, "liststore1");
-  g_object_unref (builder);
-
-  g_object_weak_ref (model, (GWeakNotify)model_weakref, NULL);
-
-  g_assert (model_freed == FALSE);
-  gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), NULL);
-  g_assert (model_freed == TRUE);
-  
-  gtk_widget_destroy (GTK_WIDGET (window));
-
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  g_object_unref (builder);
-}
-
-static void
-test_icon_factory (void)
-{
-  GtkBuilder *builder;
-  const gchar buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
-    "    <sources>"
-    "      <source stock-id=\"apple-red\" filename=\"apple-red.png\"/>"
-    "    </sources>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
-    "    <sources>"
-    "      <source stock-id=\"sliff\" direction=\"rtl\" state=\"active\""
-    "              size=\"menu\" filename=\"sloff.png\"/>"
-    "      <source stock-id=\"sliff\" direction=\"ltr\" state=\"selected\""
-    "              size=\"dnd\" filename=\"slurf.png\"/>"
-    "    </sources>"
-    "  </object>"
-    "</interface>";
-#if 0
-  const gchar buffer3[] =
-    "<interface>"
-    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
-    "    <invalid/>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer4[] =
-    "<interface>"
-    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
-    "    <sources>"
-    "      <invalid/>"
-    "    </sources>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer5[] =
-    "<interface>"
-    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
-    "    <sources>"
-    "      <source/>"
-    "    </sources>"
-    "  </object>"
-    "</interface>";
-  GError *error = NULL;
-#endif  
-  GObject *factory;
-  GtkIconSet *icon_set;
-  GtkIconSource *icon_source;
-  GtkWidget *image;
-  
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  factory = gtk_builder_get_object (builder, "iconfactory1");
-  g_assert (factory != NULL);
-
-  icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (factory), "apple-red");
-  g_assert (icon_set != NULL);
-  gtk_icon_factory_add_default (GTK_ICON_FACTORY (factory));
-  image = gtk_image_new_from_stock ("apple-red", GTK_ICON_SIZE_BUTTON);
-  g_assert (image != NULL);
-  g_object_ref_sink (image);
-  g_object_unref (image);
-
-  g_object_unref (builder);
-
-  builder = builder_new_from_string (buffer2, -1, NULL);
-  factory = gtk_builder_get_object (builder, "iconfactory1");
-  g_assert (factory != NULL);
-
-  icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (factory), "sliff");
-  g_assert (icon_set != NULL);
-  g_assert (g_slist_length (icon_set->sources) == 2);
-
-  icon_source = icon_set->sources->data;
-  g_assert (gtk_icon_source_get_direction (icon_source) == GTK_TEXT_DIR_RTL);
-  g_assert (gtk_icon_source_get_state (icon_source) == GTK_STATE_ACTIVE);
-  g_assert (gtk_icon_source_get_size (icon_source) == GTK_ICON_SIZE_MENU);
-  g_assert (g_str_has_suffix (gtk_icon_source_get_filename (icon_source), "sloff.png"));
-  
-  icon_source = icon_set->sources->next->data;
-  g_assert (gtk_icon_source_get_direction (icon_source) == GTK_TEXT_DIR_LTR);
-  g_assert (gtk_icon_source_get_state (icon_source) == GTK_STATE_SELECTED);
-  g_assert (gtk_icon_source_get_size (icon_source) == GTK_ICON_SIZE_DND);
-  g_assert (g_str_has_suffix (gtk_icon_source_get_filename (icon_source), "slurf.png"));
-
-  g_object_unref (builder);
-
-#if 0
-  error = NULL;
-  gtk_builder_add_from_string (builder, buffer3, -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_TAG));
-  g_error_free (error);
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, buffer4, -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_TAG));
-  g_error_free (error);
-
-  error = NULL;
-  gtk_builder_add_from_string (builder, buffer5, -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
-  g_error_free (error);
-#endif
-
-}
-
-typedef struct {
-  gboolean weight;
-  gboolean foreground;
-  gboolean underline;
-  gboolean size;
-  gboolean font_desc;
-  gboolean language;
-} FoundAttrs;
-
-static gboolean 
-filter_pango_attrs (PangoAttribute *attr, 
-                   gpointer        data)
-{
-  FoundAttrs *found = (FoundAttrs *)data;
-
-  if (attr->klass->type == PANGO_ATTR_WEIGHT)
-    found->weight = TRUE;
-  else if (attr->klass->type == PANGO_ATTR_FOREGROUND)
-    found->foreground = TRUE;
-  else if (attr->klass->type == PANGO_ATTR_UNDERLINE)
-    found->underline = TRUE;
-  /* Make sure optional start/end properties are working */
-  else if (attr->klass->type == PANGO_ATTR_SIZE && 
-          attr->start_index == 5 &&
-          attr->end_index   == 10)
-    found->size = TRUE;
-  else if (attr->klass->type == PANGO_ATTR_FONT_DESC)
-    found->font_desc = TRUE;
-  else if (attr->klass->type == PANGO_ATTR_LANGUAGE)
-    found->language = TRUE;
-
-  return TRUE;
-}
-
-static void
-test_pango_attributes (void)
-{
-  GtkBuilder *builder;
-  FoundAttrs found = { 0, };
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkLabel\" id=\"label1\">"
-    "    <attributes>"
-    "      <attribute name=\"weight\" value=\"PANGO_WEIGHT_BOLD\"/>"
-    "      <attribute name=\"foreground\" value=\"DarkSlateGray\"/>"
-    "      <attribute name=\"underline\" value=\"True\"/>"
-    "      <attribute name=\"size\" value=\"4\" start=\"5\" end=\"10\"/>"
-    "      <attribute name=\"font-desc\" value=\"Sans Italic 22\"/>"
-    "      <attribute name=\"language\" value=\"pt_BR\"/>"
-    "    </attributes>"
-    "  </object>"
-    "</interface>";
-  const gchar err_buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkLabel\" id=\"label1\">"
-    "    <attributes>"
-    "      <attribute name=\"weight\"/>"
-    "    </attributes>"
-    "  </object>"
-    "</interface>";
-  const gchar err_buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkLabel\" id=\"label1\">"
-    "    <attributes>"
-    "      <attribute name=\"weight\" value=\"PANGO_WEIGHT_BOLD\" unrecognized=\"True\"/>"
-    "    </attributes>"
-    "  </object>"
-    "</interface>";
-
-  GObject *label;
-  GError  *error = NULL;
-  PangoAttrList *attrs, *filtered;
-  
-  /* Test attributes are set */
-  builder = builder_new_from_string (buffer, -1, NULL);
-  label = gtk_builder_get_object (builder, "label1");
-  g_assert (label != NULL);
-
-  attrs = gtk_label_get_attributes (GTK_LABEL (label));
-  g_assert (attrs != NULL);
-
-  filtered = pango_attr_list_filter (attrs, filter_pango_attrs, &found);
-  g_assert (filtered);
-  pango_attr_list_unref (filtered);
-
-  g_assert (found.weight);
-  g_assert (found.foreground);
-  g_assert (found.underline);
-  g_assert (found.size);
-  g_assert (found.language);
-  g_assert (found.font_desc);
-
-  g_object_unref (builder);
-
-  /* Test errors are set */
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_string (builder, err_buffer1, -1, &error);
-  label = gtk_builder_get_object (builder, "label1");
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_MISSING_ATTRIBUTE));
-  g_object_unref (builder);
-  g_error_free (error);
-  error = NULL;
-
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_string (builder, err_buffer2, -1, &error);
-  label = gtk_builder_get_object (builder, "label1");
-
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
-  g_object_unref (builder);
-  g_error_free (error);
-}
-
-static void
-test_requires (void)
-{
-  GtkBuilder *builder;
-  GError     *error = NULL;
-  gchar      *buffer;
-  const gchar buffer_fmt[] =
-    "<interface>"
-    "  <requires lib=\"gtk+\" version=\"%d.%d\"/>"
-    "</interface>";
-
-  buffer = g_strdup_printf (buffer_fmt, GTK_MAJOR_VERSION, GTK_MINOR_VERSION + 1);
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_string (builder, buffer, -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_VERSION_MISMATCH));
-  g_object_unref (builder);
-  g_error_free (error);
-  g_free (buffer);
-}
-
-static void
-test_add_objects (void)
-{
-  GtkBuilder *builder;
-  GError *error;
-  gint ret;
-  GObject *obj;
-  GtkUIManager *manager;
-  GtkWidget *menubar;
-  GObject *menu, *label;
-  GList *children;
-  gchar *objects[2] = {"mainbox", NULL};
-  gchar *objects2[3] = {"mainbox", "window2", NULL};
-  gchar *objects3[3] = {"uimgr1", "menubar1"};
-  gchar *objects4[2] = {"uimgr1", NULL};
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window\">"
-    "    <child>"
-    "      <object class=\"GtkVBox\" id=\"mainbox\">"
-    "        <property name=\"visible\">True</property>"
-    "        <child>"
-    "          <object class=\"GtkLabel\" id=\"label1\">"
-    "            <property name=\"visible\">True</property>"
-    "            <property name=\"label\" translatable=\"no\">first label</property>"
-    "          </object>"
-    "        </child>"
-    "        <child>"
-    "          <object class=\"GtkLabel\" id=\"label2\">"
-    "            <property name=\"visible\">True</property>"
-    "            <property name=\"label\" translatable=\"no\">second label</property>"
-    "          </object>"
-    "          <packing>"
-    "            <property name=\"position\">1</property>"
-    "          </packing>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window2\">"
-    "    <child>"
-    "      <object class=\"GtkLabel\" id=\"label3\">"
-    "        <property name=\"label\" translatable=\"no\">second label</property>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "<interface/>";
-  const gchar buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkUIManager\" id=\"uimgr1\">"
-    "    <child>"
-    "      <object class=\"GtkActionGroup\" id=\"ag1\">"
-    "        <child>"
-    "          <object class=\"GtkAction\" id=\"file\">"
-    "            <property name=\"label\">_File</property>"
-    "          </object>"
-    "          <accelerator key=\"n\" modifiers=\"GDK_CONTROL_MASK\"/>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "    <ui>"
-    "      <menubar name=\"menubar1\">"
-    "        <menu action=\"file\">"
-    "        </menu>"
-    "      </menubar>"
-    "    </ui>"
-    "  </object>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <child>"
-    "      <object class=\"GtkMenuBar\" id=\"menubar1\" constructor=\"uimgr1\"/>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-
-  error = NULL;
-  builder = gtk_builder_new ();
-  ret = gtk_builder_add_objects_from_string (builder, buffer, -1, objects, &error);
-  g_assert (ret);
-  g_assert (error == NULL);
-  obj = gtk_builder_get_object (builder, "window");
-  g_assert (obj == NULL);
-  obj = gtk_builder_get_object (builder, "window2");
-  g_assert (obj == NULL);
-  obj = gtk_builder_get_object (builder, "mainbox");  
-  g_assert (GTK_IS_WIDGET (obj));
-  g_object_unref (builder);
-
-  error = NULL;
-  builder = gtk_builder_new ();
-  ret = gtk_builder_add_objects_from_string (builder, buffer, -1, objects2, &error);
-  g_assert (ret);
-  g_assert (error == NULL);
-  obj = gtk_builder_get_object (builder, "window");
-  g_assert (obj == NULL);
-  obj = gtk_builder_get_object (builder, "window2");
-  g_assert (GTK_IS_WINDOW (obj));
-  gtk_widget_destroy (GTK_WIDGET (obj));
-  obj = gtk_builder_get_object (builder, "mainbox");  
-  g_assert (GTK_IS_WIDGET (obj));
-  g_object_unref (builder);
-
-  /* test cherry picking a ui manager and menubar that depends on it */
-  error = NULL;
-  builder = gtk_builder_new ();
-  ret = gtk_builder_add_objects_from_string (builder, buffer2, -1, objects3, &error);
-  g_assert (ret);
-  obj = gtk_builder_get_object (builder, "uimgr1");
-  g_assert (GTK_IS_UI_MANAGER (obj));
-  obj = gtk_builder_get_object (builder, "file");
-  g_assert (GTK_IS_ACTION (obj));
-  obj = gtk_builder_get_object (builder, "menubar1");
-  g_assert (GTK_IS_MENU_BAR (obj));
-  menubar = GTK_WIDGET (obj);
-
-  children = gtk_container_get_children (GTK_CONTAINER (menubar));
-  menu = children->data;
-  g_assert (menu != NULL);
-  g_assert (GTK_IS_MENU_ITEM (menu));
-  g_assert (strcmp (gtk_widget_get_name (GTK_WIDGET (menu)), "file") == 0);
-  g_list_free (children);
-  label = G_OBJECT (gtk_bin_get_child (GTK_BIN (menu)));
-  g_assert (label != NULL);
-  g_assert (GTK_IS_LABEL (label));
-  g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
-
-  g_object_unref (builder);
-
-  /* test cherry picking just the ui manager */
-  error = NULL;
-  builder = gtk_builder_new ();
-  ret = gtk_builder_add_objects_from_string (builder, buffer2, -1, objects4, &error);
-  g_assert (ret);
-  obj = gtk_builder_get_object (builder, "uimgr1");
-  g_assert (GTK_IS_UI_MANAGER (obj));
-  manager = GTK_UI_MANAGER (obj);
-  obj = gtk_builder_get_object (builder, "file");
-  g_assert (GTK_IS_ACTION (obj));
-  menubar = gtk_ui_manager_get_widget (manager, "/menubar1");
-  g_assert (GTK_IS_MENU_BAR (menubar));
-
-  children = gtk_container_get_children (GTK_CONTAINER (menubar));
-  menu = children->data;
-  g_assert (menu != NULL);
-  g_assert (GTK_IS_MENU_ITEM (menu));
-  g_assert (strcmp (gtk_widget_get_name (GTK_WIDGET (menu)), "file") == 0);
-  g_list_free (children);
-  label = G_OBJECT (gtk_bin_get_child (GTK_BIN (menu)));
-  g_assert (label != NULL);
-  g_assert (GTK_IS_LABEL (label));
-  g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
-
-  g_object_unref (builder);
-}
-
-static GtkWidget *
-get_parent_menubar (GtkWidget *menuitem)
-{
-  GtkMenuShell *menu_shell;
-  GtkWidget *attach = NULL;
-
-  menu_shell = GTK_MENU_SHELL (gtk_widget_get_parent (menuitem));
-
-  g_assert (GTK_IS_MENU_SHELL (menu_shell));
-
-  while (menu_shell && !GTK_IS_MENU_BAR (menu_shell))
-    {
-      if (GTK_IS_MENU (menu_shell) && 
-         (attach = gtk_menu_get_attach_widget (GTK_MENU (menu_shell))) != NULL)
-       menu_shell = GTK_MENU_SHELL (gtk_widget_get_parent (attach));
-      else
-       menu_shell = NULL;
-    }
-
-  return menu_shell ? GTK_WIDGET (menu_shell) : NULL;
-}
-
-static void
-test_menus (void)
-{
-  const gchar *buffer =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <accel-groups>"
-    "      <group name=\"accelgroup1\"/>"
-    "    </accel-groups>"
-    "    <child>"
-    "      <object class=\"GtkVBox\" id=\"vbox1\">"
-    "        <property name=\"visible\">True</property>"
-    "        <property name=\"orientation\">vertical</property>"
-    "        <child>"
-    "          <object class=\"GtkMenuBar\" id=\"menubar1\">"
-    "            <property name=\"visible\">True</property>"
-    "            <child>"
-    "              <object class=\"GtkMenuItem\" id=\"menuitem1\">"
-    "                <property name=\"visible\">True</property>"
-    "                <property name=\"label\" translatable=\"yes\">_File</property>"
-    "                <property name=\"use_underline\">True</property>"
-    "                <child type=\"submenu\">"
-    "                  <object class=\"GtkMenu\" id=\"menu1\">"
-    "                    <property name=\"visible\">True</property>"
-    "                    <child>"
-    "                      <object class=\"GtkImageMenuItem\" id=\"imagemenuitem1\">"
-    "                        <property name=\"label\">gtk-new</property>"
-    "                        <property name=\"visible\">True</property>"
-    "                        <property name=\"use_stock\">True</property>"
-    "                        <property name=\"accel_group\">accelgroup1</property>"
-    "                      </object>"
-    "                    </child>"
-    "                  </object>"
-    "                </child>"
-    "              </object>"
-    "            </child>"
-    "          </object>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "<object class=\"GtkAccelGroup\" id=\"accelgroup1\"/>"
-    "</interface>";
-
-  const gchar *buffer1 =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window1\">"
-    "    <accel-groups>"
-    "      <group name=\"accelgroup1\"/>"
-    "    </accel-groups>"
-    "    <child>"
-    "      <object class=\"GtkVBox\" id=\"vbox1\">"
-    "        <property name=\"visible\">True</property>"
-    "        <property name=\"orientation\">vertical</property>"
-    "        <child>"
-    "          <object class=\"GtkMenuBar\" id=\"menubar1\">"
-    "            <property name=\"visible\">True</property>"
-    "            <child>"
-    "              <object class=\"GtkImageMenuItem\" id=\"imagemenuitem1\">"
-    "                <property name=\"visible\">True</property>"
-    "                <child>"
-    "                  <object class=\"GtkLabel\" id=\"custom1\">"
-    "                    <property name=\"visible\">True</property>"
-    "                    <property name=\"label\">a label</property>"
-    "                  </object>"
-    "                </child>"
-    "              </object>"
-    "            </child>"
-    "          </object>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "<object class=\"GtkAccelGroup\" id=\"accelgroup1\"/>"
-    "</interface>";
-  GtkBuilder *builder;
-  GtkWidget *child;
-  GtkWidget *window, *item;
-  GtkAccelGroup *accel_group;
-  GtkWidget *item_accel_label, *sample_accel_label, *sample_menu_item, *custom;
-
-  /* Check that the item has the correct accel label string set
-   */
-  builder = builder_new_from_string (buffer, -1, NULL);
-  window = (GtkWidget *)gtk_builder_get_object (builder, "window1");
-  item = (GtkWidget *)gtk_builder_get_object (builder, "imagemenuitem1");
-  accel_group = (GtkAccelGroup *)gtk_builder_get_object (builder, "accelgroup1");
-
-  gtk_widget_show_all (window);
-
-  sample_menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, accel_group);
-
-  child = gtk_bin_get_child (GTK_BIN (sample_menu_item));
-  g_assert (child);
-  g_assert (GTK_IS_ACCEL_LABEL (child));
-  sample_accel_label = child;
-  gtk_widget_show (sample_accel_label);
-
-  child = gtk_bin_get_child (GTK_BIN (item));
-  g_assert (child);
-  g_assert (GTK_IS_ACCEL_LABEL (child));
-  item_accel_label = child;
-
-  gtk_accel_label_refetch (GTK_ACCEL_LABEL (sample_accel_label));
-  gtk_accel_label_refetch (GTK_ACCEL_LABEL (item_accel_label));
-
-  g_assert (gtk_label_get_text (GTK_LABEL (sample_accel_label)) != NULL);
-  g_assert (gtk_label_get_text (GTK_LABEL (item_accel_label)) != NULL);
-  g_assert (strcmp (gtk_label_get_text (GTK_LABEL (item_accel_label)),
-                   gtk_label_get_text (GTK_LABEL (sample_accel_label))) == 0);
-
-  /* Check the menu hierarchy worked here  */
-  g_assert (get_parent_menubar (item));
-
-  gtk_widget_destroy (GTK_WIDGET (window));
-  gtk_widget_destroy (sample_menu_item);
-  g_object_unref (builder);
-
-
-  /* Check that we can add alien children to menu items via normal
-   * GtkContainer apis.
-   */
-  builder = builder_new_from_string (buffer1, -1, NULL);
-  window = (GtkWidget *)gtk_builder_get_object (builder, "window1");
-  item = (GtkWidget *)gtk_builder_get_object (builder, "imagemenuitem1");
-  custom = (GtkWidget *)gtk_builder_get_object (builder, "custom1");
-
-  g_assert (gtk_widget_get_parent (custom) == item);
-
-  gtk_widget_destroy (GTK_WIDGET (window));
-  g_object_unref (builder);
-
-}
-
-
-static void 
-test_file (const gchar *filename)
-{
-  GtkBuilder *builder;
-  GError *error = NULL;
-  GSList *l, *objects;
-
-  builder = gtk_builder_new ();
-
-  if (!gtk_builder_add_from_file (builder, filename, &error))
-    {
-      g_error ("%s", error->message);
-      g_error_free (error);
-      return;
-    }
-
-  objects = gtk_builder_get_objects (builder);
-  for (l = objects; l; l = l->next)
-    {
-      GObject *obj = (GObject*)l->data;
-
-      if (GTK_IS_DIALOG (obj))
-       {
-         g_print ("Running dialog %s.\n",
-                  gtk_widget_get_name (GTK_WIDGET (obj)));
-         gtk_dialog_run (GTK_DIALOG (obj));
-       }
-      else if (GTK_IS_WINDOW (obj))
-       {
-         g_signal_connect (obj, "destroy", G_CALLBACK (gtk_main_quit), NULL);
-         g_print ("Showing %s.\n",
-                  gtk_widget_get_name (GTK_WIDGET (obj)));
-         gtk_widget_show_all (GTK_WIDGET (obj));
-       }
-    }
-
-  gtk_main ();
-
-  g_object_unref (builder);
-  builder = NULL;
-}
-
-static void
-test_message_area (void)
-{
-  GtkBuilder *builder;
-  GObject *obj, *obj1;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkInfoBar\" id=\"infobar1\">"
-    "    <child internal-child=\"content_area\">"
-    "      <object class=\"GtkHBox\" id=\"contentarea1\">"
-    "        <child>"
-    "          <object class=\"GtkLabel\" id=\"content\">"
-    "            <property name=\"label\" translatable=\"yes\">Message</property>"
-    "          </object>"
-    "          <packing>"
-    "            <property name='expand'>False</property>"
-    "          </packing>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "    <child internal-child=\"action_area\">"
-    "      <object class=\"GtkVButtonBox\" id=\"actionarea1\">"
-    "        <child>"
-    "          <object class=\"GtkButton\" id=\"button_ok\">"
-    "            <property name=\"label\">gtk-ok</property>"
-    "            <property name=\"use-stock\">yes</property>"
-    "          </object>"
-    "        </child>"
-    "      </object>"
-    "    </child>"
-    "    <action-widgets>"
-    "      <action-widget response=\"1\">button_ok</action-widget>"
-    "    </action-widgets>"
-    "  </object>"
-    "</interface>";
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  obj = gtk_builder_get_object (builder, "infobar1");
-  g_assert (GTK_IS_INFO_BAR (obj));
-  obj1 = gtk_builder_get_object (builder, "content");
-  g_assert (GTK_IS_LABEL (obj1));
-  g_assert (gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (obj1))) == GTK_WIDGET (obj));
-
-  obj1 = gtk_builder_get_object (builder, "button_ok");
-  g_assert (GTK_IS_BUTTON (obj1));
-  g_assert (gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (obj1))) == GTK_WIDGET (obj));
-
-  g_object_unref (builder);
-}
-
-static void
-test_gmenu (void)
-{
-  GtkBuilder *builder;
-  GObject *obj, *obj1;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window\">"
-    "  </object>"
-    "  <menu id='edit-menu'>"
-    "    <section>"
-    "      <item>"
-    "        <attribute name='label'>Undo</attribute>"
-    "        <attribute name='action'>undo</attribute>"
-    "      </item>"
-    "      <item>"
-    "        <attribute name='label'>Redo</attribute>"
-    "        <attribute name='action'>redo</attribute>"
-    "      </item>"
-    "    </section>"
-    "    <section></section>"
-    "    <section>"
-    "      <attribute name='label'>Copy &amp; Paste</attribute>"
-    "      <item>"
-    "        <attribute name='label'>Cut</attribute>"
-    "        <attribute name='action'>cut</attribute>"
-    "      </item>"
-    "      <item>"
-    "        <attribute name='label'>Copy</attribute>"
-    "        <attribute name='action'>copy</attribute>"
-    "      </item>"
-    "      <item>"
-    "        <attribute name='label'>Paste</attribute>"
-    "        <attribute name='action'>paste</attribute>"
-    "      </item>"
-    "    </section>"
-    "    <item><link name='section' id='blargh'>"
-    "      <item>"
-    "        <attribute name='label'>Bold</attribute>"
-    "        <attribute name='action'>bold</attribute>"
-    "      </item>"
-    "      <submenu>"
-    "        <attribute name='label'>Language</attribute>"
-    "        <item>"
-    "          <attribute name='label'>Latin</attribute>"
-    "          <attribute name='action'>lang</attribute>"
-    "          <attribute name='target'>'latin'</attribute>"
-    "        </item>"
-    "        <item>"
-    "          <attribute name='label'>Greek</attribute>"
-    "          <attribute name='action'>lang</attribute>"
-    "          <attribute name='target'>'greek'</attribute>"
-    "        </item>"
-    "        <item>"
-    "          <attribute name='label'>Urdu</attribute>"
-    "          <attribute name='action'>lang</attribute>"
-    "          <attribute name='target'>'urdu'</attribute>"
-    "        </item>"
-    "      </submenu>"
-    "    </link></item>"
-    "  </menu>"
-    "</interface>";
-
-  builder = builder_new_from_string (buffer, -1, NULL);
-  obj = gtk_builder_get_object (builder, "window");
-  g_assert (GTK_IS_WINDOW (obj));
-  obj1 = gtk_builder_get_object (builder, "edit-menu");
-  g_assert (G_IS_MENU_MODEL (obj1));
-  obj1 = gtk_builder_get_object (builder, "blargh");
-  g_assert (G_IS_MENU_MODEL (obj1));
-  g_object_unref (builder);
-}
-
-static void
-test_level_bar (void)
-{
-  GtkBuilder *builder;
-  GError *error = NULL;
-  GObject *obj, *obj1;
-  const gchar buffer1[] =
-    "<interface>"
-    "  <object class=\"GtkWindow\" id=\"window\">"
-    "    <child>"
-    "      <object class=\"GtkLevelBar\" id=\"levelbar\">"
-    "        <property name=\"value\">4.70</property>"
-    "        <property name=\"min-value\">2</property>"
-    "        <property name=\"max-value\">5</property>"
-    "        <offsets>"
-    "          <offset name=\"low\" value=\"2.25\"/>"
-    "          <offset name=\"custom\" value=\"3\"/>"
-    "          <offset name=\"high\" value=\"3\"/>"
-    "        </offsets>"
-    "      </object>"
-    "    </child>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer2[] =
-    "<interface>"
-    "  <object class=\"GtkLevelBar\" id=\"levelbar\">"
-    "    <offsets>"
-    "      <offset name=\"low\" bogus_attr=\"foo\"/>"
-    "    </offsets>"
-    "  </object>"
-    "</interface>";
-  const gchar buffer3[] =
-    "<interface>"
-    "  <object class=\"GtkLevelBar\" id=\"levelbar\">"
-    "    <offsets>"
-    "      <offset name=\"low\" value=\"1\"/>"
-    "    </offsets>"
-    "    <bogus_tag>"
-    "    </bogus_tag>"
-    "  </object>"
-    "</interface>";
-
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_string (builder, buffer1, -1, &error);
-  g_assert (error == NULL);
-
-  obj = gtk_builder_get_object (builder, "window");
-  g_assert (GTK_IS_WINDOW (obj));
-  obj1 = gtk_builder_get_object (builder, "levelbar");
-  g_assert (GTK_IS_LEVEL_BAR (obj1));
-  g_object_unref (builder);
-
-  error = NULL;
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_string (builder, buffer2, -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
-  g_error_free (error);
-  g_object_unref (builder);
-
-  error = NULL;
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_string (builder, buffer3, -1, &error);
-  g_assert (g_error_matches (error,
-                             GTK_BUILDER_ERROR,
-                             GTK_BUILDER_ERROR_UNHANDLED_TAG));
-  g_error_free (error);
-  g_object_unref (builder);
-}
-
-static GObject *external_object = NULL, *external_object_swapped = NULL;
-
-void
-on_button_clicked (GtkButton *button, GObject *data)
-{
-  external_object = data;
-}
-
-void
-on_button_clicked_swapped (GObject *data, GtkButton *button)
-{
-  external_object_swapped = data;
-}
-
-static void
-test_expose_object (void)
-{
-  GtkBuilder *builder;
-  GError *error = NULL;
-  GtkWidget *image;
-  GObject *obj;
-  const gchar buffer[] =
-    "<interface>"
-    "  <object class=\"GtkButton\" id=\"button\">"
-    "    <property name=\"image\">external_image</property>"
-    "    <signal name=\"clicked\" handler=\"on_button_clicked\" object=\"builder\" swapped=\"no\"/>"
-    "    <signal name=\"clicked\" handler=\"on_button_clicked_swapped\" object=\"builder\"/>"
-    "  </object>"
-    "</interface>";
-
-  image = gtk_image_new ();
-  builder = gtk_builder_new ();
-  gtk_builder_expose_object (builder, "external_image", G_OBJECT (image));
-  gtk_builder_expose_object (builder, "builder", G_OBJECT (builder));
-  gtk_builder_add_from_string (builder, buffer, -1, &error);
-  g_assert (error == NULL);
-
-  obj = gtk_builder_get_object (builder, "button");
-  g_assert (GTK_IS_BUTTON (obj));
-
-  g_assert (gtk_button_get_image (GTK_BUTTON (obj)) == image);
-
-  /* Connect signals and fake clicked event */
-  gtk_builder_connect_signals (builder, NULL);
-  gtk_button_clicked (GTK_BUTTON (obj));
-
-  g_assert (external_object == G_OBJECT (builder));
-  g_assert (external_object_swapped == G_OBJECT (builder));
-}
-
-int
-main (int argc, char **argv)
-{
-  /* initialize test program */
-  gtk_test_init (&argc, &argv);
-
-  if (argc > 1)
-    {
-      test_file (argv[1]);
-      return 0;
-    }
-
-  g_test_add_func ("/Builder/Parser", test_parser);
-  g_test_add_func ("/Builder/Types", test_types);
-  g_test_add_func ("/Builder/Construct-Only Properties", test_construct_only_property);
-  g_test_add_func ("/Builder/Children", test_children);
-  g_test_add_func ("/Builder/Child Properties", test_child_properties);
-  g_test_add_func ("/Builder/Object Properties", test_object_properties);
-  g_test_add_func ("/Builder/Notebook", test_notebook);
-  g_test_add_func ("/Builder/Domain", test_domain);
-  g_test_add_func ("/Builder/Signal Autoconnect", test_connect_signals);
-  g_test_add_func ("/Builder/UIManager Simple", test_uimanager_simple);
-  g_test_add_func ("/Builder/Spin Button", test_spin_button);
-  g_test_add_func ("/Builder/SizeGroup", test_sizegroup);
-  g_test_add_func ("/Builder/ListStore", test_list_store);
-  g_test_add_func ("/Builder/TreeStore", test_tree_store);
-  g_test_add_func ("/Builder/TreeView Column", test_treeview_column);
-  g_test_add_func ("/Builder/IconView", test_icon_view);
-  g_test_add_func ("/Builder/ComboBox", test_combo_box);
-#if 0
-  g_test_add_func ("/Builder/ComboBox Entry", test_combo_box_entry);
-#endif
-  g_test_add_func ("/Builder/CellView", test_cell_view);
-  g_test_add_func ("/Builder/Dialog", test_dialog);
-  g_test_add_func ("/Builder/Accelerators", test_accelerators);
-  g_test_add_func ("/Builder/Widget", test_widget);
-  g_test_add_func ("/Builder/Value From String", test_value_from_string);
-  g_test_add_func ("/Builder/Reference Counting", test_reference_counting);
-  g_test_add_func ("/Builder/Window", test_window);
-  g_test_add_func ("/Builder/IconFactory", test_icon_factory);
-  g_test_add_func ("/Builder/PangoAttributes", test_pango_attributes);
-  g_test_add_func ("/Builder/Requires", test_requires);
-  g_test_add_func ("/Builder/AddObjects", test_add_objects);
-  g_test_add_func ("/Builder/Menus", test_menus);
-  g_test_add_func ("/Builder/MessageArea", test_message_area);
-  g_test_add_func ("/Builder/MessageDialog", test_message_dialog);
-  g_test_add_func ("/Builder/GMenu", test_gmenu);
-  g_test_add_func ("/Builder/LevelBar", test_level_bar);
-  g_test_add_func ("/Builder/Expose Object", test_expose_object);
-
-  return g_test_run();
-}
-
diff --git a/gtk/tests/cellarea.c b/gtk/tests/cellarea.c
deleted file mode 100644 (file)
index 98072ed..0000000
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * Copyright (C) 2011 Red Hat, Inc.
- * Author: Matthias Clasen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-/* tests related to handling of the cell-area property in
- * GtkCellLayout implementations
- */
-
-/* test that we have a cell area after new() */
-static void
-test_iconview_new (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  view = gtk_icon_view_new ();
-
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == gtk_icon_view_get_item_orientation (GTK_ICON_VIEW (view)));
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that new_with_area() keeps the provided area */
-static void
-test_iconview_new_with_area (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  view = gtk_icon_view_new_with_area (area);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that g_object_new keeps the provided area */
-static void
-test_iconview_object_new (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
-  view = g_object_new (GTK_TYPE_ICON_VIEW, "cell-area", area, NULL);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == gtk_icon_view_get_item_orientation (GTK_ICON_VIEW (view)));
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-typedef GtkIconView MyIconView;
-typedef GtkIconViewClass MyIconViewClass;
-
-GType my_icon_view_get_type (void);
-
-G_DEFINE_TYPE (MyIconView, my_icon_view, GTK_TYPE_ICON_VIEW)
-
-static void
-my_icon_view_class_init (MyIconViewClass *klass)
-{
-}
-
-static gint subclass_init;
-
-static void
-my_icon_view_init (MyIconView *view)
-{
-  GtkCellArea *area;
-
-  if (subclass_init == 0)
-    {
-      /* do nothing to area */
-    }
-  else if (subclass_init == 1)
-    {
-      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-      g_assert (GTK_IS_CELL_AREA_BOX (area));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
-    }
-}
-
-/* test that an iconview subclass has an area */
-static void
-test_iconview_subclass0 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  view = g_object_new (my_icon_view_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that an iconview subclass keeps the provided area */
-static void
-test_iconview_subclass1 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  area = gtk_cell_area_box_new ();
-  view = g_object_new (my_icon_view_get_type (), "cell-area", area, NULL);
-  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test we can access the area in subclass init */
-static void
-test_iconview_subclass2 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 1;
-
-  view = g_object_new (my_icon_view_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test we get a warning if an area is provided, but ignored */
-static void
-test_iconview_subclass3 (void)
-{
-  subclass_init = 1;
-
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      GtkWidget *view;
-      GtkCellArea *area;
-
-      area = gtk_cell_area_box_new ();
-      view = g_object_new (my_icon_view_get_type (), "cell-area", area, NULL);
-      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-      g_object_ref_sink (view);
-      g_object_unref (view);
-
-      exit (0);
-    }
-  g_test_trap_assert_failed ();
-  g_test_trap_assert_stderr ("*ignoring construct property*");
-}
-
-/* test that we have a cell area after new() */
-static void
-test_combobox_new (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  view = gtk_combo_box_new ();
-
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that new_with_area() keeps the provided area */
-static void
-test_combobox_new_with_area (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  view = gtk_combo_box_new_with_area (area);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that g_object_new keeps the provided area */
-static void
-test_combobox_object_new (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
-  view = g_object_new (GTK_TYPE_COMBO_BOX, "cell-area", area, NULL);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-typedef GtkComboBox MyComboBox;
-typedef GtkComboBoxClass MyComboBoxClass;
-
-GType my_combo_box_get_type (void);
-
-G_DEFINE_TYPE (MyComboBox, my_combo_box, GTK_TYPE_COMBO_BOX)
-
-static void
-my_combo_box_class_init (MyComboBoxClass *klass)
-{
-}
-
-static void
-my_combo_box_init (MyComboBox *view)
-{
-  GtkCellArea *area;
-
-  if (subclass_init == 0)
-    {
-      /* do nothing to area */
-    }
-  else if (subclass_init == 1)
-    {
-      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-      g_assert (GTK_IS_CELL_AREA_BOX (area));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
-    }
-}
-
-/* test that a combobox subclass has an area */
-static void
-test_combobox_subclass0 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  view = g_object_new (my_combo_box_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that a combobox subclass keeps the provided area */
-static void
-test_combobox_subclass1 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  area = gtk_cell_area_box_new ();
-  view = g_object_new (my_combo_box_get_type (), "cell-area", area, NULL);
-  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test we can access the area in subclass init */
-static void
-test_combobox_subclass2 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 1;
-
-  view = g_object_new (my_combo_box_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test we get a warning if an area is provided, but ignored */
-static void
-test_combobox_subclass3 (void)
-{
-  subclass_init = 1;
-
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      GtkWidget *view;
-      GtkCellArea *area;
-
-      area = gtk_cell_area_box_new ();
-      view = g_object_new (my_combo_box_get_type (), "cell-area", area, NULL);
-      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-      g_object_ref_sink (view);
-      g_object_unref (view);
-
-      exit (0);
-    }
-  g_test_trap_assert_failed ();
-  g_test_trap_assert_stderr ("*ignoring construct property*");
-}
-
-/* test that we have a cell area after new() */
-static void
-test_cellview_new (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  view = gtk_cell_view_new ();
-
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that new_with_context() keeps the provided area */
-static void
-test_cellview_new_with_context (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-  GtkCellAreaContext *context;
-
-  area = gtk_cell_area_box_new ();
-  context = gtk_cell_area_create_context (area);
-  view = gtk_cell_view_new_with_context (area, context);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that g_object_new keeps the provided area */
-static void
-test_cellview_object_new (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
-  view = g_object_new (GTK_TYPE_CELL_VIEW, "cell-area", area, NULL);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-typedef GtkCellView MyCellView;
-typedef GtkCellViewClass MyCellViewClass;
-
-GType my_cell_view_get_type (void);
-
-G_DEFINE_TYPE (MyCellView, my_cell_view, GTK_TYPE_CELL_VIEW)
-
-static void
-my_cell_view_class_init (MyCellViewClass *klass)
-{
-}
-
-static void
-my_cell_view_init (MyCellView *view)
-{
-  GtkCellArea *area;
-
-  if (subclass_init == 0)
-    {
-      /* do nothing to area */
-    }
-  else if (subclass_init == 1)
-    {
-      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-      g_assert (GTK_IS_CELL_AREA_BOX (area));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
-    }
-}
-
-/* test that a cellview subclass has an area */
-static void
-test_cellview_subclass0 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  view = g_object_new (my_cell_view_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test that a cellview subclass keeps the provided area */
-static void
-test_cellview_subclass1 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  area = gtk_cell_area_box_new ();
-  view = g_object_new (my_cell_view_get_type (), "cell-area", area, NULL);
-  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test we can access the area in subclass init */
-static void
-test_cellview_subclass2 (void)
-{
-  GtkWidget *view;
-  GtkCellArea *area;
-
-  subclass_init = 1;
-
-  view = g_object_new (my_cell_view_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-  g_object_ref_sink (view);
-  g_object_unref (view);
-}
-
-/* test we get a warning if an area is provided, but ignored */
-static void
-test_cellview_subclass3 (void)
-{
-  subclass_init = 1;
-
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      GtkWidget *view;
-      GtkCellArea *area;
-
-      area = gtk_cell_area_box_new ();
-      view = g_object_new (my_cell_view_get_type (), "cell-area", area, NULL);
-      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-      g_object_ref_sink (view);
-      g_object_unref (view);
-
-      exit (0);
-    }
-  g_test_trap_assert_failed ();
-  g_test_trap_assert_stderr ("*ignoring construct property*");
-}
-
-/* test that we have a cell area after new() */
-static void
-test_column_new (void)
-{
-  GtkTreeViewColumn *col;
-  GtkCellArea *area;
-
-  col = gtk_tree_view_column_new ();
-
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-
-  g_object_ref_sink (col);
-  g_object_unref (col);
-}
-
-/* test that new_with_area() keeps the provided area */
-static void
-test_column_new_with_area (void)
-{
-  GtkTreeViewColumn *col;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  col = gtk_tree_view_column_new_with_area (area);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)) == area);
-
-  g_object_ref_sink (col);
-  g_object_unref (col);
-}
-
-/* test that g_object_new keeps the provided area */
-static void
-test_column_object_new (void)
-{
-  GtkTreeViewColumn *col;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
-  col = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN, "cell-area", area, NULL);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)) == area);
-
-  g_object_ref_sink (col);
-  g_object_unref (col);
-}
-
-typedef GtkTreeViewColumn MyTreeViewColumn;
-typedef GtkTreeViewColumnClass MyTreeViewColumnClass;
-
-GType my_tree_view_column_get_type (void);
-
-G_DEFINE_TYPE (MyTreeViewColumn, my_tree_view_column, GTK_TYPE_TREE_VIEW_COLUMN)
-
-static void
-my_tree_view_column_class_init (MyTreeViewColumnClass *klass)
-{
-}
-
-static void
-my_tree_view_column_init (MyTreeViewColumn *col)
-{
-  GtkCellArea *area;
-
-  if (subclass_init == 0)
-    {
-      /* do nothing to area */
-    }
-  else if (subclass_init == 1)
-    {
-      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
-      g_assert (GTK_IS_CELL_AREA_BOX (area));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
-    }
-}
-
-/* test that a column subclass has an area */
-static void
-test_column_subclass0 (void)
-{
-  GtkTreeViewColumn *col;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  col = g_object_new (my_tree_view_column_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (col);
-  g_object_unref (col);
-}
-
-/* test that a column subclass keeps the provided area */
-static void
-test_column_subclass1 (void)
-{
-  GtkTreeViewColumn *col;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  area = gtk_cell_area_box_new ();
-  col = g_object_new (my_tree_view_column_get_type (), "cell-area", area, NULL);
-  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (col);
-  g_object_unref (col);
-}
-
-/* test we can access the area in subclass init */
-static void
-test_column_subclass2 (void)
-{
-  GtkTreeViewColumn *col;
-  GtkCellArea *area;
-
-  subclass_init = 1;
-
-  col = g_object_new (my_tree_view_column_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-  g_object_ref_sink (col);
-  g_object_unref (col);
-}
-
-/* test we get a warning if an area is provided, but ignored */
-static void
-test_column_subclass3 (void)
-{
-  subclass_init = 1;
-
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      GtkTreeViewColumn *col;
-      GtkCellArea *area;
-
-      area = gtk_cell_area_box_new ();
-      col = g_object_new (my_tree_view_column_get_type (), "cell-area", area, NULL);
-      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-      g_object_ref_sink (col);
-      g_object_unref (col);
-
-      exit (0);
-    }
-  g_test_trap_assert_failed ();
-  g_test_trap_assert_stderr ("*ignoring construct property*");
-}
-
-/* test that we have a cell area after new() */
-static void
-test_completion_new (void)
-{
-  GtkEntryCompletion *c;
-  GtkCellArea *area;
-
-  c = gtk_entry_completion_new ();
-
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-
-  g_object_ref_sink (c);
-  g_object_unref (c);
-}
-
-/* test that new_with_area() keeps the provided area */
-static void
-test_completion_new_with_area (void)
-{
-  GtkEntryCompletion *c;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  c = gtk_entry_completion_new_with_area (area);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)) == area);
-
-  g_object_ref_sink (c);
-  g_object_unref (c);
-}
-
-/* test that g_object_new keeps the provided area */
-static void
-test_completion_object_new (void)
-{
-  GtkEntryCompletion *c;
-  GtkCellArea *area;
-
-  area = gtk_cell_area_box_new ();
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
-  c = g_object_new (GTK_TYPE_ENTRY_COMPLETION, "cell-area", area, NULL);
-  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)) == area);
-
-  g_object_ref_sink (c);
-  g_object_unref (c);
-}
-
-typedef GtkEntryCompletion MyEntryCompletion;
-typedef GtkEntryCompletionClass MyEntryCompletionClass;
-
-GType my_entry_completion_get_type (void);
-
-G_DEFINE_TYPE (MyEntryCompletion, my_entry_completion, GTK_TYPE_ENTRY_COMPLETION)
-
-static void
-my_entry_completion_class_init (MyEntryCompletionClass *klass)
-{
-}
-
-static void
-my_entry_completion_init (MyEntryCompletion *c)
-{
-  GtkCellArea *area;
-
-  if (subclass_init == 0)
-    {
-      /* do nothing to area */
-    }
-  else if (subclass_init == 1)
-    {
-      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
-      g_assert (GTK_IS_CELL_AREA_BOX (area));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
-    }
-}
-
-/* test that a completion subclass has an area */
-static void
-test_completion_subclass0 (void)
-{
-  GtkEntryCompletion *c;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  c = g_object_new (my_entry_completion_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (c);
-  g_object_unref (c);
-}
-
-/* test that a completion subclass keeps the provided area */
-static void
-test_completion_subclass1 (void)
-{
-  GtkEntryCompletion *c;
-  GtkCellArea *area;
-
-  subclass_init = 0;
-
-  area = gtk_cell_area_box_new ();
-  c = g_object_new (my_entry_completion_get_type (), "cell-area", area, NULL);
-  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
-
-  g_object_ref_sink (c);
-  g_object_unref (c);
-}
-
-/* test we can access the area in subclass init */
-static void
-test_completion_subclass2 (void)
-{
-  GtkEntryCompletion *c;
-  GtkCellArea *area;
-
-  subclass_init = 1;
-
-  c = g_object_new (my_entry_completion_get_type (), NULL);
-  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
-  g_assert (GTK_IS_CELL_AREA_BOX (area));
-  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-  g_object_ref_sink (c);
-  g_object_unref (c);
-}
-
-/* test we get a warning if an area is provided, but ignored */
-static void
-test_completion_subclass3 (void)
-{
-  subclass_init = 1;
-
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      GtkEntryCompletion *c;
-      GtkCellArea *area;
-
-      area = gtk_cell_area_box_new ();
-      c = g_object_new (my_entry_completion_get_type (), "cell-area", area, NULL);
-      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)));
-      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
-
-      g_object_ref_sink (c);
-      g_object_unref (c);
-
-      exit (0);
-    }
-  g_test_trap_assert_failed ();
-  g_test_trap_assert_stderr ("*ignoring construct property*");
-}
-
-int
-main (int argc, char *argv[])
-{
-  gtk_test_init (&argc, &argv);
-  g_test_bug_base ("http://bugzilla.gnome.org/");
-  gtk_test_register_all_types();
-
-  g_test_add_func ("/tests/iconview-new", test_iconview_new);
-  g_test_add_func ("/tests/iconview-new-with-area", test_iconview_new_with_area);
-  g_test_add_func ("/tests/iconview-object-new", test_iconview_object_new);
-  g_test_add_func ("/tests/iconview-subclass0", test_iconview_subclass0);
-  g_test_add_func ("/tests/iconview-subclass1", test_iconview_subclass1);
-  g_test_add_func ("/tests/iconview-subclass2", test_iconview_subclass2);
-  g_test_add_func ("/tests/iconview-subclass3", test_iconview_subclass3);
-
-  g_test_add_func ("/tests/combobox-new", test_combobox_new);
-  g_test_add_func ("/tests/combobox-new-with-area", test_combobox_new_with_area);
-  g_test_add_func ("/tests/combobox-object-new", test_combobox_object_new);
-  g_test_add_func ("/tests/combobox-subclass0", test_combobox_subclass0);
-  g_test_add_func ("/tests/combobox-subclass1", test_combobox_subclass1);
-  g_test_add_func ("/tests/combobox-subclass2", test_combobox_subclass2);
-  g_test_add_func ("/tests/combobox-subclass3", test_combobox_subclass3);
-
-  g_test_add_func ("/tests/cellview-new", test_cellview_new);
-  g_test_add_func ("/tests/cellview-new-with-context", test_cellview_new_with_context);
-  g_test_add_func ("/tests/cellview-object-new", test_cellview_object_new);
-  g_test_add_func ("/tests/cellview-subclass0", test_cellview_subclass0);
-  g_test_add_func ("/tests/cellview-subclass1", test_cellview_subclass1);
-  g_test_add_func ("/tests/cellview-subclass2", test_cellview_subclass2);
-  g_test_add_func ("/tests/cellview-subclass3", test_cellview_subclass3);
-
-  g_test_add_func ("/tests/column-new", test_column_new);
-  g_test_add_func ("/tests/column-new-with-area", test_column_new_with_area);
-  g_test_add_func ("/tests/column-object-new", test_column_object_new);
-  g_test_add_func ("/tests/column-subclass0", test_column_subclass0);
-  g_test_add_func ("/tests/column-subclass1", test_column_subclass1);
-  g_test_add_func ("/tests/column-subclass2", test_column_subclass2);
-  g_test_add_func ("/tests/column-subclass3", test_column_subclass3);
-
-  g_test_add_func ("/tests/completion-new", test_completion_new);
-  g_test_add_func ("/tests/completion-new-with-area", test_completion_new_with_area);
-  g_test_add_func ("/tests/completion-object-new", test_completion_object_new);
-  g_test_add_func ("/tests/completion-subclass0", test_completion_subclass0);
-  g_test_add_func ("/tests/completion-subclass1", test_completion_subclass1);
-  g_test_add_func ("/tests/completion-subclass2", test_completion_subclass2);
-  g_test_add_func ("/tests/completion-subclass3", test_completion_subclass3);
-
-  return g_test_run();
-}
diff --git a/gtk/tests/crossingevents.c b/gtk/tests/crossingevents.c
deleted file mode 100644 (file)
index be210f3..0000000
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * crossingevents.c: A test for crossing events
- *
- * Copyright (C) 2008 Cody Russell
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-#include <string.h>
-
-typedef struct {
-  GtkWidget *window;
-  GtkWidget *eventbox;
-  GtkWidget *frame;
-  GtkWidget *button;
-  GtkWidget *check;
-  gboolean   events_connected;
-  GQueue    *queue;
-} CrossingTest;
-
-typedef struct {
-  gboolean entered;
-  gchar *name;
-  gboolean synthesized;
-  GdkCrossingMode mode;
-  GdkNotifyType detail;
-} CrossingEventData;
-
-#define SLEEP_DURATION    100
-
-void start_events (CrossingTest *test);
-void stop_events (CrossingTest *test);
-
-static gboolean
-sleep_timeout_cb (gpointer data)
-{
-  gtk_main_quit ();
-  return FALSE;
-}
-
-static void
-sleep_in_main_loop (double fraction)
-{
-  /* process all pending idles and events */
-  while (g_main_context_pending (NULL))
-    g_main_context_iteration (NULL, FALSE);
-  /* sleeping probably isn't strictly necessary here */
-  gdk_threads_add_timeout_full (G_MAXINT, fraction * SLEEP_DURATION, sleep_timeout_cb, NULL, NULL);
-  gtk_main ();
-  /* process any pending idles or events that arrived during sleep */
-  while (g_main_context_pending (NULL))
-    g_main_context_iteration (NULL, FALSE);
-}
-
-void
-set_cursor (GtkWidget *widget)
-{
-  int x, y, w, h;
-
-  gdk_window_get_origin (widget->window, &x, &y);
-
-  x += widget->allocation.x;
-  y += widget->allocation.y;
-  w = widget->allocation.width;
-  h = widget->allocation.height;
-
-  gdk_display_warp_pointer (gtk_widget_get_display (widget),
-                           gtk_widget_get_screen (widget),
-                           x + w / 2,
-                           y + h / 2);
-
-  sleep_in_main_loop (0.5);
-}
-
-static gboolean
-on_enter (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
-{
-  CrossingTest *test = (CrossingTest*)user_data;
-
-  CrossingEventData *evt = g_slice_new0 (CrossingEventData);
-  evt->entered = TRUE;
-  evt->name = g_strdup (gtk_widget_get_name (widget));
-  evt->synthesized = event->send_event;
-  evt->mode = event->mode;
-  evt->detail = event->detail;
-
-  if (!test->queue)
-    test->queue = g_queue_new ();
-
-  g_queue_push_tail (test->queue, evt);
-
-  return FALSE;
-}
-
-static gboolean
-on_leave (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
-{
-  CrossingTest *test = (CrossingTest*)user_data;
-
-  CrossingEventData *evt = g_slice_new0 (CrossingEventData);
-  evt->entered = FALSE;
-  evt->name = g_strdup (gtk_widget_get_name (widget));
-  evt->synthesized = event->send_event;
-  evt->mode = event->mode;
-  evt->detail = event->detail;
-
-  if (!test->queue)
-    test->queue = g_queue_new ();
-
-  g_queue_push_tail (test->queue, evt);
-
-  return FALSE;
-}
-
-static void
-on_check_toggled (GtkWidget *toggle, GtkWidget *button)
-{
-  gtk_widget_set_sensitive (button, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)));
-}
-
-static void
-sensitivity_setup (CrossingTest *test,
-                  gconstpointer user_data)
-{
-  GtkWidget *frame;
-
-  test->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_widget_set_name (test->window, "W");
-  frame = gtk_frame_new ("Crossing Events");
-  test->eventbox = gtk_event_box_new ();
-  gtk_widget_set_name (test->eventbox, "E");
-
-  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 10);
-  gtk_container_add (GTK_CONTAINER (test->window), frame);
-  gtk_container_add (GTK_CONTAINER (frame), test->eventbox);
-  gtk_container_add (GTK_CONTAINER (test->eventbox), vbox);
-
-  test->button = gtk_button_new_with_label ("Click me!");
-  gtk_widget_set_name (test->button, "B");
-  gtk_box_pack_start (GTK_BOX (vbox), test->button, FALSE, TRUE, 0);
-
-  test->check = gtk_check_button_new_with_label ("Sensitive?");
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), TRUE);
-  g_signal_connect (G_OBJECT (test->check),
-                   "toggled", G_CALLBACK (on_check_toggled), test->button);
-  gtk_widget_set_name (test->check, "C");
-  gtk_box_pack_start (GTK_BOX (vbox), test->check, FALSE, TRUE, 0);
-
-  gtk_widget_show_all (test->window);
-
-  gtk_window_move (GTK_WINDOW (test->window), 0, 0);
-
-  sleep_in_main_loop (0.5);
-}
-
-static void
-sensitivity_teardown (CrossingTest *test,
-                     gconstpointer user_data)
-{
-  stop_events (test);
-  gtk_widget_destroy (test->window);
-
-  if (test->queue != NULL)
-    {
-      g_queue_clear (test->queue);
-      test->queue = NULL;
-    }
-}
-
-void
-start_events (CrossingTest *test)
-{
-  if (!test->events_connected)
-    {
-      g_object_connect (G_OBJECT (test->window),
-                       "signal::destroy", gtk_main_quit, NULL,
-                       "signal::enter-notify-event", on_enter, test,
-                       "signal::leave-notify-event", on_leave, test,
-                       NULL);
-      g_object_connect (G_OBJECT (test->eventbox),
-                       "signal::enter-notify-event", on_enter, test,
-                       "signal::leave-notify-event", on_leave, test,
-                       NULL);
-      g_object_connect (G_OBJECT (test->button),
-                       "signal::enter-notify-event", on_enter, test,
-                       "signal::leave-notify-event", on_leave, test,
-                       NULL);
-      g_object_connect (G_OBJECT (test->check),
-                       "signal::enter-notify-event", on_enter, test,
-                       "signal::leave-notify-event", on_leave, test,
-                       NULL);
-      test->events_connected = TRUE;
-    }
-
-  sleep_in_main_loop (0.5);
-}
-
-void
-stop_events (CrossingTest *test)
-{
-  if (test->events_connected)
-    {
-      g_object_disconnect (G_OBJECT (test->window),
-                          "any_signal", gtk_main_quit, NULL,
-                          "any_signal", on_enter, test,
-                          "any_signal", on_leave, test,
-                          NULL);
-      g_object_disconnect (G_OBJECT (test->eventbox),
-                          "any_signal", on_enter, test,
-                          "any_signal", on_leave, test,
-                          NULL);
-      g_object_disconnect (G_OBJECT (test->button),
-                          "any_signal", on_enter, test,
-                          "any_signal", on_leave, test,
-                          NULL);
-      g_object_disconnect (G_OBJECT (test->check),
-                          "any_signal", G_CALLBACK (on_check_toggled), test->button,
-                          "any_signal", on_enter, test,
-                          "any_signal", on_leave, test,
-                          NULL);
-      test->events_connected = FALSE;
-    }
-}
-
-void
-move_cursor_away (CrossingTest *test)
-{
-  gdk_display_warp_pointer (gtk_widget_get_display (test->window),
-                            gtk_widget_get_screen (test->window),
-                            1000, -1000);
-
-  sleep_in_main_loop (0.5);
-}
-
-void
-check_event (CrossingTest *test,
-            const gchar *name,
-            gboolean entered,
-            gboolean synthesized,
-            GdkCrossingMode mode,
-            GdkNotifyType detail)
-{
-  CrossingEventData *evt;
-
-  g_assert (test->queue != NULL);
-
-  evt = g_queue_pop_head (test->queue);
-
-  g_assert (evt->entered == entered);
-  g_assert (strcmp (evt->name, name) == 0);
-  g_assert (evt->synthesized == synthesized);
-  g_assert (evt->mode == mode);
-
-  if (evt->detail != detail)
-    g_print ("%s %s event, detail %d, expected detail %d\n", 
-             synthesized ? "synthesized" : "native",
-             entered ? "enter" : "leave",
-             evt->detail, detail);
-  g_assert (evt->detail == detail);
-}
-
-/* Verify crossing events when moving into and out of a sensitive widget */
-static void
-cursor_on_sensitive (CrossingTest *test,
-                    gconstpointer user_data)
-{
-  move_cursor_away (test);
-
-  start_events (test);
-
-  set_cursor (test->button);
-
-  check_event (test,
-              "W",
-              TRUE,
-              FALSE,  /* native */
-              GDK_CROSSING_NORMAL,
-              GDK_NOTIFY_NONLINEAR_VIRTUAL);
-
-  check_event (test,
-              "E",
-              TRUE,
-              FALSE,  /* native */
-              GDK_CROSSING_NORMAL,
-              GDK_NOTIFY_NONLINEAR_VIRTUAL);
-
-  check_event (test,
-              "B",
-              TRUE,
-              FALSE,  /* native */
-              GDK_CROSSING_NORMAL,
-              GDK_NOTIFY_NONLINEAR);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  move_cursor_away (test);
-
-  check_event (test,
-              "B",
-              FALSE,
-              FALSE,  /* native */
-              GDK_CROSSING_NORMAL,
-              GDK_NOTIFY_NONLINEAR);
-
-  check_event (test,
-              "E",
-              FALSE,
-              FALSE,  /* native */
-              GDK_CROSSING_NORMAL,
-              GDK_NOTIFY_NONLINEAR_VIRTUAL);
-
-  check_event (test,
-              "W",
-              FALSE,
-              FALSE,  /* native */
-              GDK_CROSSING_NORMAL,
-              GDK_NOTIFY_NONLINEAR_VIRTUAL);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-static void
-change_sensitive_to_insensitive (CrossingTest *test,
-                                gconstpointer user_data)
-{
-  move_cursor_away (test);
-  set_cursor (test->button);
-
-  start_events (test);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
-
-  check_event (test,
-              "B",
-              FALSE,
-              TRUE,  /* synthesized */
-              GDK_CROSSING_STATE_CHANGED,
-              GDK_NOTIFY_ANCESTOR);
-
-  check_event (test,
-               "E",
-              FALSE,
-              TRUE,  /* synthesized */
-               GDK_CROSSING_STATE_CHANGED,
-               GDK_NOTIFY_VIRTUAL);
-
-  check_event (test,
-               "W",
-              FALSE,
-              TRUE,  /* synthesized */
-               GDK_CROSSING_STATE_CHANGED,
-               GDK_NOTIFY_VIRTUAL);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-static void
-change_insensitive_to_sensitive (CrossingTest *test,
-                                gconstpointer user_data)
-{
-  move_cursor_away (test);
-  set_cursor (test->button);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
-
-  start_events (test);
-
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), TRUE);
-
-  check_event (test,
-               "W",
-               TRUE,
-               TRUE,  /* synthesized */
-               GDK_CROSSING_STATE_CHANGED,
-               GDK_NOTIFY_VIRTUAL);
-
-  check_event (test,
-               "E",
-               TRUE,
-              TRUE,  /* synthesized */
-               GDK_CROSSING_STATE_CHANGED,
-               GDK_NOTIFY_VIRTUAL);
-
-  check_event (test,
-               "B",
-               TRUE,
-              TRUE,  /* synthesized */
-               GDK_CROSSING_STATE_CHANGED,
-               GDK_NOTIFY_ANCESTOR);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-static void
-cursor_from_insensitive_to_sensitive (CrossingTest *test,
-                                     gconstpointer user_data)
-{
-  set_cursor (test->button);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
-
-  start_events (test);
-
-  set_cursor (test->check);
-
-  check_event (test,
-               "C",
-               TRUE,
-               FALSE,  /* native */
-               GDK_CROSSING_NORMAL,
-               GDK_NOTIFY_NONLINEAR);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-static void
-cursor_from_sensitive_to_insensitive (CrossingTest *test,
-                                     gconstpointer user_data)
-{
-  set_cursor (test->check);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
-
-  start_events (test);
-
-  set_cursor (test->button);
-
-  check_event (test,
-               "C",
-               FALSE,
-               FALSE,  /* native */
-               GDK_CROSSING_NORMAL,
-               GDK_NOTIFY_NONLINEAR);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-static void
-add_gtk_grab (CrossingTest *test,
-             gconstpointer user_data)
-{
-  set_cursor (test->button);
-
-  start_events (test);
-
-  gtk_grab_add (test->check);
-
-  check_event (test,
-              "B",
-              FALSE,
-              TRUE,   /* synthesized */
-              GDK_CROSSING_GTK_GRAB,
-              GDK_NOTIFY_ANCESTOR);
-
-  check_event (test,
-               "E",
-               FALSE,
-              TRUE,   /* synthesized */
-              GDK_CROSSING_GTK_GRAB,
-              GDK_NOTIFY_ANCESTOR);
-
-  check_event (test,
-               "W",
-               FALSE,
-               TRUE,   /* synthesized */
-               GDK_CROSSING_GTK_GRAB,
-              GDK_NOTIFY_ANCESTOR);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-static void
-remove_gtk_grab (CrossingTest *test,
-                gconstpointer user_data)
-{
-  set_cursor (test->button);
-
-  gtk_grab_add (test->check);
-
-  start_events (test);
-
-  gtk_grab_remove (test->check);
-
-  check_event (test,
-               "B",
-               TRUE,
-               TRUE,   /* synthesized */
-               GDK_CROSSING_GTK_UNGRAB,
-              GDK_NOTIFY_ANCESTOR);
-
-  check_event (test,
-               "E",
-               TRUE,
-               TRUE,   /* synthesized */
-              GDK_CROSSING_GTK_UNGRAB,
-               GDK_NOTIFY_ANCESTOR);
-
-  check_event (test,
-               "W",
-               TRUE,
-               TRUE,   /* synthesized */
-               GDK_CROSSING_GTK_UNGRAB,
-               GDK_NOTIFY_ANCESTOR);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-static void
-cursor_from_shadowed_to_unshadowed (CrossingTest *test,
-                                   gconstpointer user_data)
-{
-  set_cursor (test->button);
-
-  gtk_grab_add (test->check);
-
-  start_events (test);
-
-  set_cursor (test->check);
-
-  check_event (test,
-               "C",
-               FALSE,
-               FALSE,   /* native */
-               GDK_CROSSING_NORMAL,
-               GDK_NOTIFY_NONLINEAR);
-
-  check_event (test,
-               "C",
-               TRUE,
-               FALSE,   /* native */
-               GDK_CROSSING_NORMAL,
-               GDK_NOTIFY_NONLINEAR);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-static void
-cursor_from_unshadowed_to_shadowed (CrossingTest *test,
-                                   gconstpointer user_data)
-{
-  set_cursor (test->check);
-
-  gtk_grab_add (test->check);
-
-  start_events (test);
-
-  set_cursor (test->button);
-
-  check_event (test,
-               "C",
-               FALSE,
-               FALSE,   /* native */
-               GDK_CROSSING_NORMAL,
-               GDK_NOTIFY_NONLINEAR);
-
-  check_event (test,
-               "C",
-               TRUE,
-               FALSE,   /* native */
-               GDK_CROSSING_NORMAL,
-               GDK_NOTIFY_NONLINEAR);
-
-  g_assert (g_queue_is_empty (test->queue));
-
-  stop_events (test);
-}
-
-int
-main (int    argc,
-      char **argv)
-{
-  gtk_test_init (&argc, &argv, NULL);
-
-  g_test_add ("/crossings/cursor-on-sensitive", CrossingTest, NULL,
-             sensitivity_setup, cursor_on_sensitive, sensitivity_teardown);
-
-  g_test_add ("/crossings/change-sensitive-to-insensitive", CrossingTest, NULL,
-             sensitivity_setup, change_sensitive_to_insensitive, sensitivity_teardown);
-
-  g_test_add ("/crossings/cursor-from-insensitive-to-sensitive", CrossingTest, NULL,
-             sensitivity_setup, cursor_from_insensitive_to_sensitive, sensitivity_teardown);
-
-  g_test_add ("/crossings/cursor-from-sensitive-to-insensitive", CrossingTest, NULL,
-             sensitivity_setup, cursor_from_sensitive_to_insensitive, sensitivity_teardown);
-
-  g_test_add ("/crossings/change-insensitive-to-sensitive", CrossingTest, NULL,
-             sensitivity_setup, change_insensitive_to_sensitive, sensitivity_teardown);
-
-  g_test_add ("/crossings/add-gtk-grab", CrossingTest, NULL,
-             sensitivity_setup, add_gtk_grab, sensitivity_teardown);
-
-  g_test_add ("/crossings/remove-gtk-grab", CrossingTest, NULL,
-             sensitivity_setup, remove_gtk_grab, sensitivity_teardown);
-
-  g_test_add ("/crossings/cursor-from-shadowed-to-unshadowed", CrossingTest, NULL,
-             sensitivity_setup, cursor_from_shadowed_to_unshadowed, sensitivity_teardown);
-
-  g_test_add ("/crossings/cursor-from-unshadowed-to-shadowed", CrossingTest, NULL,
-             sensitivity_setup, cursor_from_unshadowed_to_shadowed, sensitivity_teardown);
-
-  return g_test_run ();
-}
diff --git a/gtk/tests/defaultvalue.c b/gtk/tests/defaultvalue.c
deleted file mode 100644 (file)
index ce1ad3b..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/* Gtk+ default value tests
- * Copyright (C) 2007 Christian Persch
- *               2007 Johan Dahlin
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <gtk/gtkunixprint.h>
-
-static void
-check_property (const char *output,
-               GParamSpec *pspec,
-               GValue *value)
-{
-  GValue default_value = G_VALUE_INIT;
-  char *v, *dv, *msg;
-
-  if (g_param_value_defaults (pspec, value))
-      return;
-
-  g_value_init (&default_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-  g_param_value_set_default (pspec, &default_value);
-      
-  v = g_strdup_value_contents (value);
-  dv = g_strdup_value_contents (&default_value);
-  
-  msg = g_strdup_printf ("%s %s.%s: %s != %s\n",
-                        output,
-                        g_type_name (pspec->owner_type),
-                        pspec->name,
-                        dv, v);
-  g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__,
-                      G_STRFUNC, msg);
-  g_free (msg);
-  
-  g_free (v);
-  g_free (dv);
-  g_value_unset (&default_value);
-}
-
-static void
-test_type (gconstpointer data)
-{
-  GObjectClass *klass;
-  GObject *instance;
-  GParamSpec **pspecs;
-  guint n_pspecs, i;
-  GType type;
-
-  type = * (GType *) data;
-
-  if (!G_TYPE_IS_CLASSED (type))
-    return;
-
-  if (G_TYPE_IS_ABSTRACT (type))
-    return;
-
-  if (!g_type_is_a (type, G_TYPE_OBJECT))
-    return;
-
-  /* These can't be freely constructed/destroyed */
-  if (g_type_is_a (type, GTK_TYPE_PRINT_JOB) ||
-      g_type_is_a (type, GTK_TYPE_APPLICATION) ||
-      g_type_is_a (type, GDK_TYPE_PIXBUF_LOADER) ||
-      g_type_is_a (type, gdk_pixbuf_simple_anim_iter_get_type ()))
-    return;
-
-  klass = g_type_class_ref (type);
-  
-  if (g_type_is_a (type, GTK_TYPE_SETTINGS))
-    instance = g_object_ref (gtk_settings_get_default ());
-  else if (g_type_is_a (type, GDK_TYPE_WINDOW))
-    {
-      GdkWindowAttr attributes;
-      attributes.window_type = GDK_WINDOW_TEMP;
-      attributes.event_mask = 0;
-      attributes.width = 100;
-      attributes.height = 100;
-      instance = g_object_ref (gdk_window_new (NULL, &attributes, 0));
-    }
-  else
-    instance = g_object_new (type, NULL);
-
-  if (g_type_is_a (type, G_TYPE_INITIALLY_UNOWNED))
-    g_object_ref_sink (instance);
-
-  pspecs = g_object_class_list_properties (klass, &n_pspecs);
-  for (i = 0; i < n_pspecs; ++i)
-    {
-      GParamSpec *pspec = pspecs[i];
-      GValue value = G_VALUE_INIT;
-      
-      if (pspec->owner_type != type)
-       continue;
-
-      if ((pspec->flags & G_PARAM_READABLE) == 0)
-       continue;
-
-      if (g_type_is_a (type, GDK_TYPE_DISPLAY_MANAGER) &&
-         (strcmp (pspec->name, "default-display") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_ABOUT_DIALOG) &&
-         (strcmp (pspec->name, "program-name") == 0))
-       continue;
-      
-      /* These are set to the current date */
-      if (g_type_is_a (type, GTK_TYPE_CALENDAR) &&
-         (strcmp (pspec->name, "year") == 0 ||
-          strcmp (pspec->name, "month") == 0 ||
-          strcmp (pspec->name, "day") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_CELL_RENDERER_TEXT) &&
-         (strcmp (pspec->name, "background-gdk") == 0 ||
-          strcmp (pspec->name, "foreground-gdk") == 0 ||
-          strcmp (pspec->name, "font") == 0 ||
-          strcmp (pspec->name, "font-desc") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_CELL_VIEW) &&
-         (strcmp (pspec->name, "background-gdk") == 0 ||
-          strcmp (pspec->name, "foreground-gdk") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_COLOR_BUTTON) &&
-         strcmp (pspec->name, "color") == 0)
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_COLOR_SELECTION) &&
-         strcmp (pspec->name, "current-color") == 0)
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_COLOR_SELECTION_DIALOG) &&
-         (strcmp (pspec->name, "color-selection") == 0 ||
-          strcmp (pspec->name, "ok-button") == 0 ||
-          strcmp (pspec->name, "help-button") == 0 ||
-          strcmp (pspec->name, "cancel-button") == 0))
-       continue;
-
-      /* Default invisible char is determined at runtime */
-      if (g_type_is_a (type, GTK_TYPE_ENTRY) &&
-         (strcmp (pspec->name, "invisible-char") == 0 ||
-           strcmp (pspec->name, "buffer") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_FONT_SELECTION) &&
-         strcmp (pspec->name, "font") == 0)
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_LAYOUT) &&
-         (strcmp (pspec->name, "hadjustment") == 0 ||
-           strcmp (pspec->name, "vadjustment") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_MESSAGE_DIALOG) &&
-          (strcmp (pspec->name, "image") == 0 ||
-           strcmp (pspec->name, "message-area") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_PANED) &&
-         strcmp (pspec->name, "max-position") == 0)
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_PRINT_OPERATION) &&
-         strcmp (pspec->name, "job-name") == 0)
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_PRINT_UNIX_DIALOG) &&
-         (strcmp (pspec->name, "page-setup") == 0 ||
-          strcmp (pspec->name, "print-settings") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_PROGRESS_BAR) &&
-          strcmp (pspec->name, "adjustment") == 0)
-        continue;
-
-      /* filename value depends on $HOME */
-      if (g_type_is_a (type, GTK_TYPE_RECENT_MANAGER) &&
-          (strcmp (pspec->name, "filename") == 0 ||
-          strcmp (pspec->name, "size") == 0))
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_SCALE_BUTTON) &&
-          strcmp (pspec->name, "adjustment") == 0)
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_SCROLLED_WINDOW) &&
-         (strcmp (pspec->name, "hadjustment") == 0 ||
-           strcmp (pspec->name, "vadjustment") == 0))
-       continue;
-
-      /* these defaults come from XResources */
-      if (g_type_is_a (type, GTK_TYPE_SETTINGS) &&
-          strncmp (pspec->name, "gtk-xft-", 8) == 0)
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_SETTINGS) &&
-          (strcmp (pspec->name, "color-hash") == 0 ||
-          strcmp (pspec->name, "gtk-cursor-theme-name") == 0 ||
-          strcmp (pspec->name, "gtk-cursor-theme-size") == 0 ||
-          strcmp (pspec->name, "gtk-dnd-drag-threshold") == 0 ||
-          strcmp (pspec->name, "gtk-double-click-time") == 0 ||
-          strcmp (pspec->name, "gtk-fallback-icon-theme") == 0 ||
-          strcmp (pspec->name, "gtk-file-chooser-backend") == 0 ||
-          strcmp (pspec->name, "gtk-icon-theme-name") == 0 ||
-          strcmp (pspec->name, "gtk-im-module") == 0 ||
-          strcmp (pspec->name, "gtk-key-theme-name") == 0 ||
-          strcmp (pspec->name, "gtk-theme-name") == 0 ||
-           strcmp (pspec->name, "gtk-sound-theme-name") == 0 ||
-           strcmp (pspec->name, "gtk-enable-input-feedback-sounds") == 0 ||
-           strcmp (pspec->name, "gtk-enable-event-sounds") == 0))
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_SPIN_BUTTON) &&
-          (strcmp (pspec->name, "adjustment") == 0))
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_STATUS_ICON) &&
-          (strcmp (pspec->name, "size") == 0 ||
-           strcmp (pspec->name, "screen") == 0))
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_TEXT_BUFFER) &&
-          (strcmp (pspec->name, "tag-table") == 0 ||
-           strcmp (pspec->name, "copy-target-list") == 0 ||
-           strcmp (pspec->name, "paste-target-list") == 0))
-        continue;
-
-      /* language depends on the current locale */
-      if (g_type_is_a (type, GTK_TYPE_TEXT_TAG) &&
-          (strcmp (pspec->name, "background-gdk") == 0 ||
-           strcmp (pspec->name, "foreground-gdk") == 0 ||
-          strcmp (pspec->name, "language") == 0 ||
-          strcmp (pspec->name, "font") == 0 ||
-          strcmp (pspec->name, "font-desc") == 0))
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_TEXT_VIEW) &&
-          strcmp (pspec->name, "buffer") == 0)
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_TOOL_ITEM_GROUP) &&
-          strcmp (pspec->name, "label-widget") == 0)
-        continue;
-
-      if (g_type_is_a (type, GTK_TYPE_TREE_VIEW) &&
-         (strcmp (pspec->name, "hadjustment") == 0 ||
-           strcmp (pspec->name, "vadjustment") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_VIEWPORT) &&
-         (strcmp (pspec->name, "hadjustment") == 0 ||
-           strcmp (pspec->name, "vadjustment") == 0))
-       continue;
-
-      if (g_type_is_a (type, GTK_TYPE_WIDGET) &&
-         (strcmp (pspec->name, "name") == 0 ||
-          strcmp (pspec->name, "screen") == 0 ||
-          strcmp (pspec->name, "style") == 0))
-       continue;
-
-      /* resize-grip-visible is determined at runtime */
-      if (g_type_is_a (type, GTK_TYPE_WINDOW) &&
-          (strcmp (pspec->name, "resize-grip-visible") == 0))
-        continue;
-
-      if (g_test_verbose ())
-      g_print ("Property %s.%s\n", 
-            g_type_name (pspec->owner_type),
-            pspec->name);
-      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-      g_object_get_property (instance, pspec->name, &value);
-      check_property ("Property", pspec, &value);
-      g_value_unset (&value);
-    }
-  g_free (pspecs);
-
-  if (g_type_is_a (type, GTK_TYPE_WIDGET))
-    {
-      pspecs = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (klass), &n_pspecs);
-      
-      for (i = 0; i < n_pspecs; ++i)
-       {
-         GParamSpec *pspec = pspecs[i];
-         GValue value = G_VALUE_INIT;
-         
-         if (pspec->owner_type != type)
-           continue;
-
-         if ((pspec->flags & G_PARAM_READABLE) == 0)
-           continue;
-         
-         g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-         gtk_widget_style_get_property (GTK_WIDGET (instance), pspec->name, &value);
-         check_property ("Style property", pspec, &value);
-         g_value_unset (&value);
-       }
-
-      g_free (pspecs);
-    }
-  
-  if (g_type_is_a (type, GDK_TYPE_WINDOW))
-    gdk_window_destroy (GDK_WINDOW (instance));
-  else
-    g_object_unref (instance);
-  
-  g_type_class_unref (klass);
-}
-
-int
-main (int argc, char **argv)
-{
-  const GType *otypes;
-  guint i;
-
-  gtk_test_init (&argc, &argv);
-  gtk_test_register_all_types();
-  
-  otypes = gtk_test_list_all_types (NULL);
-  for (i = 0; otypes[i]; i++)
-    {
-      gchar *testname;
-      
-      testname = g_strdup_printf ("/Default Values/%s",
-                                 g_type_name (otypes[i]));
-      g_test_add_data_func (testname,
-                            &otypes[i],
-                           test_type);
-      g_free (testname);
-    }
-  
-  return g_test_run();
-}
diff --git a/gtk/tests/entry.c b/gtk/tests/entry.c
deleted file mode 100644 (file)
index 074f5a5..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2011 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-static gint serial = 0;
-
-typedef struct {
-  gint serial;
-  gint count;
-  gint start;
-  gint end;
-  gchar *text;
-  gchar *new_text;
-  gint position;
-  gint length;
-} EntryData;
-
-static void
-notify (GtkEditable *editable, GParamSpec *pspec, EntryData *data)
-{
-  data->serial = serial++;
-  data->count++;
-  data->text = gtk_editable_get_chars (editable, 0, -1);
-  gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
-
-#if 0
-  g_print ("notify::%s\n", pspec->name);
-  g_print ("\ttext: %s\n", data->text);
-  g_print ("\tstart: %d\n", data->start);
-  g_print ("\tend: %d\n", data->end);
-#endif
-}
-
-static void
-insert_text (GtkEditable *editable,
-             const gchar *new_text,
-             gint         new_text_length,
-             gint        *position,
-             EntryData   *data)
-{
-  data->serial = serial++;
-  data->count++;
-  data->text = gtk_editable_get_chars (editable, 0, -1);
-  gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
-  data->new_text = g_strdup (new_text);
-  data->position = *position;
-  data->length = new_text_length;
-
-#if 0
-  g_print ("insert-text \"%s\", %d\n", new_text, *position);
-  g_print ("\ttext: %s\n", data->text);
-  g_print ("\tstart: %d\n", data->start);
-  g_print ("\tend: %d\n", data->end);
-#endif
-}
-
-static void
-delete_text (GtkEditable *editable,
-             gint         start_pos,
-             gint         end_pos,
-             EntryData   *data)
-{
-  data->serial = serial++;
-  data->count++;
-  data->text = gtk_editable_get_chars (editable, 0, -1);
-  gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
-  data->position = start_pos;
-  data->length = end_pos - start_pos;
-
-#if 0
-  g_print ("delete-text %d %d\n", start_pos, end_pos);
-  g_print ("\ttext: %s\n", data->text);
-  g_print ("\tstart: %d\n", data->start);
-  g_print ("\tend: %d\n", data->end);
-#endif
-}
-
-static void
-changed (GtkEditable *editable,
-         EntryData   *data)
-{
-  data->serial = serial++;
-  data->count++;
-  data->text = gtk_editable_get_chars (editable, 0, -1);
-  gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
-
-#if 0
-  g_print ("changed\n");
-  g_print ("\ttext: %s\n", data->text);
-  g_print ("\tstart: %d\n", data->start);
-  g_print ("\tend: %d\n", data->end);
-#endif
-}
-
-static void
-test_insert (void)
-{
-  GtkWidget *entry;
-  gint pos;
-  EntryData data1;
-  EntryData data2;
-  EntryData data3;
-  EntryData data4;
-  EntryData data5;
-  EntryData data6;
-
-  entry = gtk_entry_new ();
-  g_object_ref_sink (entry);
-
-  gtk_entry_set_text (GTK_ENTRY (entry), "bar");
-  gtk_editable_set_position (GTK_EDITABLE (entry), -1);
-  pos = gtk_editable_get_position (GTK_EDITABLE (entry));
-  g_assert_cmpint (pos, ==, 3);
-
-  data1.count = 0;
-  data2.count = 0;
-  data3.count = 0;
-  data4.count = 0;
-  data5.count = 0;
-  data6.count = 0;
-  g_signal_connect (entry, "notify::cursor-position",
-                    G_CALLBACK (notify), &data1);
-  g_signal_connect (entry, "notify::selection-bound",
-                    G_CALLBACK (notify), &data2);
-  g_signal_connect (entry, "notify::text",
-                    G_CALLBACK (notify), &data3);
-  g_signal_connect (entry, "insert-text",
-                    G_CALLBACK (insert_text), &data4);
-  g_signal_connect (entry, "delete-text",
-                    G_CALLBACK (delete_text), &data5);
-  g_signal_connect (entry, "changed",
-                    G_CALLBACK (changed), &data6);
-
-  pos = 0;
-  gtk_editable_insert_text (GTK_EDITABLE (entry), "foo", -1, &pos);
-  g_assert_cmpint (pos, ==, 3);
-
-  pos = gtk_editable_get_position (GTK_EDITABLE (entry));
-  g_assert_cmpint (pos, ==, 6);
-
-  /* Check that notification for ::text, ::cursor-position and
-   * ::selection-bound happens in a consistent state after the
-   * change.
-   */
-  g_assert_cmpint (data1.count, ==, 1);
-  g_assert_cmpint (data1.start, ==, 6);
-  g_assert_cmpint (data1.end, ==, 6);
-  g_assert_cmpstr (data1.text, ==, "foobar");
-  g_free (data1.text);
-
-  g_assert_cmpint (data2.count, ==, 1);
-  g_assert_cmpint (data2.start, ==, 6);
-  g_assert_cmpint (data2.end, ==, 6);
-  g_assert_cmpstr (data2.text, ==, "foobar");
-  g_free (data2.text);
-
-  g_assert_cmpint (data3.count, ==, 1);
-  g_assert_cmpint (data3.start, ==, 6);
-  g_assert_cmpint (data3.end, ==, 6);
-  g_assert_cmpstr (data3.text, ==, "foobar");
-  g_free (data3.text);
-
-  /* Check that ::insert-text sees the state _before_ the insertion */
-  g_assert_cmpint (data4.count, ==, 1);
-  g_assert_cmpint (data4.start, ==, 3);
-  g_assert_cmpint (data4.end, ==, 3);
-  g_assert_cmpstr (data4.text, ==, "bar");
-  g_assert_cmpint (data4.position, ==, 0);
-  g_assert_cmpint (data4.length, ==, 3);
-  g_assert_cmpstr (data4.new_text, ==, "foo");
-  g_free (data4.text);
-  g_free (data4.new_text);
-
-  /* no deletion here */
-  g_assert_cmpint (data5.count, ==, 0);
-
-  /* Check that ::changed sees the post-change state */
-  g_assert_cmpint (data6.count, ==, 1);
-  g_assert_cmpint (data6.start, ==, 6);
-  g_assert_cmpint (data6.end, ==, 6);
-  g_assert_cmpstr (data6.text, ==, "foobar");
-  g_free (data6.text);
-
-  /* Now check ordering: ::insert-text comes before ::notify */
-  g_assert_cmpint (data4.serial, <, data1.serial);
-  g_assert_cmpint (data4.serial, <, data2.serial);
-  g_assert_cmpint (data4.serial, <, data3.serial);
-
-  /* ... and ::changed comes after ::notify */
-  g_assert_cmpint (data6.serial, >, data1.serial);
-  g_assert_cmpint (data6.serial, >, data2.serial);
-  g_assert_cmpint (data6.serial, >, data3.serial);
-
-  g_object_unref (entry);
-}
-
-static void
-test_delete (void)
-{
-  GtkWidget *entry;
-  gint pos;
-  EntryData data1;
-  EntryData data2;
-  EntryData data3;
-  EntryData data4;
-  EntryData data5;
-  EntryData data6;
-
-  entry = gtk_entry_new ();
-  g_object_ref_sink (entry);
-
-  gtk_entry_set_text (GTK_ENTRY (entry), "foobar");
-  gtk_editable_set_position (GTK_EDITABLE (entry), -1);
-  pos = gtk_editable_get_position (GTK_EDITABLE (entry));
-  g_assert_cmpint (pos, ==, 6);
-
-  data1.count = 0;
-  data2.count = 0;
-  data3.count = 0;
-  data4.count = 0;
-  data5.count = 0;
-  data6.count = 0;
-  g_signal_connect (entry, "notify::cursor-position",
-                    G_CALLBACK (notify), &data1);
-  g_signal_connect (entry, "notify::selection-bound",
-                    G_CALLBACK (notify), &data2);
-  g_signal_connect (entry, "notify::text",
-                    G_CALLBACK (notify), &data3);
-  g_signal_connect (entry, "insert-text",
-                    G_CALLBACK (insert_text), &data4);
-  g_signal_connect (entry, "delete-text",
-                    G_CALLBACK (delete_text), &data5);
-  g_signal_connect (entry, "changed",
-                    G_CALLBACK (changed), &data6);
-
-  gtk_editable_delete_text (GTK_EDITABLE (entry), 0, 3);
-
-  pos = gtk_editable_get_position (GTK_EDITABLE (entry));
-  g_assert_cmpint (pos, ==, 3);
-
-  /* Check that notification for ::text, ::cursor-position and
-   * ::selection-bound happens in a consistent state after the
-   * change.
-   */
-  g_assert_cmpint (data1.count, ==, 1);
-  g_assert_cmpint (data1.start, ==, 3);
-  g_assert_cmpint (data1.end, ==, 3);
-  g_assert_cmpstr (data1.text, ==, "bar");
-  g_free (data1.text);
-
-  g_assert_cmpint (data2.count, ==, 1);
-  g_assert_cmpint (data2.start, ==, 3);
-  g_assert_cmpint (data2.end, ==, 3);
-  g_assert_cmpstr (data2.text, ==, "bar");
-  g_free (data2.text);
-
-  g_assert_cmpint (data3.count, ==, 1);
-  g_assert_cmpint (data3.start, ==, 3);
-  g_assert_cmpint (data3.end, ==, 3);
-  g_assert_cmpstr (data3.text, ==, "bar");
-  g_free (data3.text);
-
-  /* no insertion here */
-  g_assert_cmpint (data4.count, ==, 0);
-
-  /* Check that ::delete-text sees the state _before_ the insertion */
-  g_assert_cmpint (data5.count, ==, 1);
-  g_assert_cmpint (data5.start, ==, 6);
-  g_assert_cmpint (data5.end, ==, 6);
-  g_assert_cmpstr (data5.text, ==, "foobar");
-  g_assert_cmpint (data5.position, ==, 0);
-  g_assert_cmpint (data5.length, ==, 3);
-  g_free (data5.text);
-
-  /* Check that ::changed sees the post-change state */
-  g_assert_cmpint (data6.count, ==, 1);
-  g_assert_cmpint (data6.start, ==, 3);
-  g_assert_cmpint (data6.end, ==, 3);
-  g_assert_cmpstr (data6.text, ==, "bar");
-  g_free (data6.text);
-
-  /* Now check ordering: ::delete-text comes before ::notify */
-  g_assert_cmpint (data5.serial, <, data1.serial);
-  g_assert_cmpint (data5.serial, <, data2.serial);
-  g_assert_cmpint (data5.serial, <, data3.serial);
-
-  /* ... and ::changed comes after ::notify */
-  g_assert_cmpint (data6.serial, >, data1.serial);
-  g_assert_cmpint (data6.serial, >, data2.serial);
-  g_assert_cmpint (data6.serial, >, data3.serial);
-  g_object_unref (entry);
-}
-
-int
-main (int   argc,
-      char *argv[])
-{
-  gtk_test_init (&argc, &argv);
-
-  g_test_add_func ("/entry/delete", test_delete);
-  g_test_add_func ("/entry/insert", test_insert);
-
-  return g_test_run();
-}
diff --git a/gtk/tests/expander.c b/gtk/tests/expander.c
deleted file mode 100644 (file)
index 87b915f..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2001.  See the AUTHORS
- * file for a list of people on the GTK+ Team.  See the ChangeLog
- * files for a list of changes.  These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
- */
-#include <gtk/gtk.h>
-
-static void
-test_click_expander (void)
-{
-  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test click on expander");
-  GtkWidget *expander = gtk_expander_new ("Test Expander");
-  GtkWidget *label = gtk_label_new ("Test Label");
-  gboolean expanded;
-  gboolean simsuccess;
-  gtk_container_add (GTK_CONTAINER (expander), label);
-  gtk_container_add (GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (window))), expander);
-  gtk_widget_show (expander);
-  gtk_widget_show (label);
-  gtk_widget_show_now (window);
-  /* check initial expander state */
-  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
-  g_assert (!expanded);
-  /* check expanding */
-  simsuccess = gtk_test_widget_click (expander, 1, 0);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
-    gtk_main_iteration ();
-  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
-  g_assert (expanded);
-  /* check collapsing */
-  simsuccess = gtk_test_widget_click (expander, 1, 0);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
-    gtk_main_iteration ();
-  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
-  g_assert (!expanded);
-}
-
-static void
-test_click_content_widget (void)
-{
-  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test click on content widget");
-  GtkWidget *expander = gtk_expander_new ("Test Expander");
-  GtkWidget *entry = gtk_entry_new ();
-  gboolean expanded;
-  gboolean simsuccess;
-  gtk_container_add (GTK_CONTAINER (expander), entry);
-  gtk_container_add (GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (window))), expander);
-  gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
-  gtk_widget_show (expander);
-  gtk_widget_show (entry);
-  gtk_widget_show_now (window);
-
-  /* check click on content with expander open */
-  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
-  g_assert (expanded);
-  simsuccess = gtk_test_widget_click (entry, 1, 0);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
-    gtk_main_iteration ();
-  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
-  g_assert (expanded);
-}
-
-int
-main (int   argc,
-      char *argv[])
-{
-  gtk_test_init (&argc, &argv);
-  g_test_add_func ("/expander/click-expander", test_click_expander);
-  g_test_add_func ("/expander/click-content-widget", test_click_content_widget);
-  return g_test_run();
-}
diff --git a/gtk/tests/file-chooser-test-dir/empty b/gtk/tests/file-chooser-test-dir/empty
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/gtk/tests/file-chooser-test-dir/text.txt b/gtk/tests/file-chooser-test-dir/text.txt
deleted file mode 100644 (file)
index cd08755..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Hello world!
diff --git a/gtk/tests/filechooser.c b/gtk/tests/filechooser.c
deleted file mode 100644 (file)
index 529f87d..0000000
+++ /dev/null
@@ -1,2492 +0,0 @@
-/* GTK - The GIMP Toolkit
- * autotestfilechooser.c: Automated unit tests for the GtkFileChooser widget
- * Copyright (C) 2005, Novell, Inc.
- *
- * Authors:
- *   Federico Mena-Quintero <federico@novell.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* TODO:
- *
- * - In test_reload_sequence(), test that the selection is preserved properly
- *   between unmap/map.
- *
- * - More tests!
- */
-
-#define SLEEP_DURATION  100
-
-#include "config.h"
-#include <string.h>
-#include <glib/gprintf.h>
-#include <gtk/gtk.h>
-#include "gtk/gtkfilechooserdefault.h"
-#include "gtk/gtkfilechooserentry.h"
-
-#if 0
-static const char *
-get_action_name (GtkFileChooserAction action)
-{
-  switch (action)
-    {
-    case GTK_FILE_CHOOSER_ACTION_OPEN:          return "OPEN";
-    case GTK_FILE_CHOOSER_ACTION_SAVE:          return "SAVE";
-    case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: return "SELECT_FOLDER";
-    case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: return "CREATE_FOLDER";
-
-    default:
-      g_assert_not_reached ();
-      return NULL;
-    }
-}
-#endif
-
-#ifdef BROKEN_TESTS
-static void
-log_test (gboolean passed, const char *test_name, ...)
-{
-  va_list args;
-  char *str;
-
-  va_start (args, test_name);
-  str = g_strdup_vprintf (test_name, args);
-  va_end (args);
-
-  if (g_test_verbose())
-    g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str);
-  g_free (str);
-}
-
-typedef void (* SetFilenameFn) (GtkFileChooser *chooser, gpointer data);
-typedef void (* CompareFilenameFn) (GtkFileChooser *chooser, gpointer data);
-
-struct test_set_filename_closure {
-  GtkWidget *chooser;
-  GtkWidget *accept_button;
-  gboolean focus_button;
-};
-
-static gboolean
-set_filename_timeout_cb (gpointer data)
-{
-  struct test_set_filename_closure *closure;
-
-  closure = data;
-
-  if (closure->focus_button)
-    gtk_widget_grab_focus (closure->accept_button);
-
-  gtk_button_clicked (GTK_BUTTON (closure->accept_button));
-
-  return FALSE;
-}
-#endif
-
-
-static guint wait_for_idle_id = 0;
-
-static gboolean
-wait_for_idle_idle (gpointer data)
-{
-  wait_for_idle_id = 0;
-
-  return G_SOURCE_REMOVE;
-}
-
-static void
-wait_for_idle (void)
-{
-  wait_for_idle_id = g_idle_add_full (G_PRIORITY_LOW + 100,
-                                     wait_for_idle_idle,
-                                     NULL, NULL);
-
-  while (wait_for_idle_id)
-    gtk_main_iteration ();
-}
-
-#ifdef BROKEN_TESTS
-static void
-test_set_filename (GtkFileChooserAction action,
-                  gboolean focus_button,
-                  SetFilenameFn set_filename_fn,const
-                  CompareFilenameFn compare_filename_fn,
-                  gpointer data)
-{
-  GtkWidget *chooser;
-  struct test_set_filename_closure closure;
-  guint timeout_id;
-
-  chooser = gtk_file_chooser_dialog_new ("hello", NULL, action,
-                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                        NULL);
-
-  closure.chooser = chooser;
-  closure.accept_button = gtk_dialog_add_button (GTK_DIALOG (chooser), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
-  closure.focus_button = focus_button;
-
-  gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
-
-  (* set_filename_fn) (GTK_FILE_CHOOSER (chooser), data);
-
-  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, set_filename_timeout_cb, &closure, NULL);
-  gtk_dialog_run (GTK_DIALOG (chooser));
-  g_source_remove (timeout_id);
-
-  (* compare_filename_fn) (GTK_FILE_CHOOSER (chooser), data);
-
-  gtk_widget_destroy (chooser);
-}
-
-static void
-set_filename_cb (GtkFileChooser *chooser, gpointer data)
-{
-  const char *filename;
-
-  filename = data;
-  gtk_file_chooser_set_filename (chooser, filename);
-}
-
-static void
-compare_filename_cb (GtkFileChooser *chooser, gpointer data)
-{
-  const char *filename;
-  char *out_filename;
-
-  filename = data;
-  out_filename = gtk_file_chooser_get_filename (chooser);
-
-  g_assert_cmpstr (out_filename, ==, filename);
-
-  if (out_filename)
-    g_free (out_filename);
-}
-
-typedef struct
-{
-  const char *test_name;
-  GtkFileChooserAction action;
-  const char *filename;
-  gboolean focus_button;
-} TestSetFilenameSetup;
-
-static void
-test_black_box_set_filename (gconstpointer data)
-{
-  const TestSetFilenameSetup *setup = data;
-
-  test_set_filename (setup->action, setup->focus_button, set_filename_cb, compare_filename_cb, (char *) setup->filename);
-}
-
-struct current_name_closure {
-       const char *path;
-       const char *current_name;
-};
-
-static void
-set_current_name_cb (GtkFileChooser *chooser, gpointer data)
-{
-  struct current_name_closure *closure;
-
-  closure = data;
-
-  gtk_file_chooser_set_current_folder (chooser, closure->path);
-  gtk_file_chooser_set_current_name (chooser, closure->current_name);
-}
-
-static void
-compare_current_name_cb (GtkFileChooser *chooser, gpointer data)
-{
-  struct current_name_closure *closure;
-  char *out_filename;
-  char *filename;
-
-  closure = data;
-
-  out_filename = gtk_file_chooser_get_filename (chooser);
-
-  g_assert (out_filename != NULL);
-
-  filename = g_build_filename (closure->path, closure->current_name, NULL);
-  g_assert_cmpstr (filename, ==, out_filename);
-
-  g_free (filename);
-  g_free (out_filename);
-}
-
-typedef struct
-{
-  const char *test_name;
-  GtkFileChooserAction action;
-  const char *current_name;
-  gboolean focus_button;
-} TestSetCurrentNameSetup;
-
-static void
-test_black_box_set_current_name (gconstpointer data)
-{
-  const TestSetCurrentNameSetup *setup = data;
-  struct current_name_closure closure;
-  char *cwd;
-
-  cwd = g_get_current_dir ();
-
-  closure.path = cwd;
-  closure.current_name = setup->current_name;
-
-  test_set_filename (setup->action, setup->focus_button, set_current_name_cb, compare_current_name_cb, &closure);
-
-  g_free (cwd);
-}
-#endif
-
-/* FIXME: fails in CREATE_FOLDER mode when FOLDER_NAME == "/" */
-
-#if 0
-#define FILE_NAME "/nonexistent"
-#define FILE_NAME_2 "/nonexistent2"
-#define FOLDER_NAME "/etc"
-#define FOLDER_NAME_2 "/usr"
-#else
-#define FILE_NAME "/etc/passwd"
-#define FILE_NAME_2 "/etc/group"
-#define FOLDER_NAME "/etc"
-#define FOLDER_NAME_2 "/usr"
-#endif
-
-#define CURRENT_NAME "parangaricutirimicuaro.txt"
-#define CURRENT_NAME_FOLDER "parangaricutirimicuaro"
-
-/* https://bugzilla.novell.com/show_bug.cgi?id=184875
- * http://bugzilla.gnome.org/show_bug.cgi?id=347066
- * http://bugzilla.gnome.org/show_bug.cgi?id=346058
- */
-
-#ifdef BROKEN_TESTS
-static void
-setup_set_filename_tests (void)
-{
-  static TestSetFilenameSetup tests[] =
-    {
-      { "/GtkFileChooser/black_box/set_filename/open/no_focus",                 GTK_FILE_CHOOSER_ACTION_OPEN,          FILE_NAME,  FALSE },
-      { "/GtkFileChooser/black_box/set_filename/open/focus",            GTK_FILE_CHOOSER_ACTION_OPEN,          FILE_NAME,  TRUE  },
-      { "/GtkFileChooser/black_box/set_filename/save/no_focus",                 GTK_FILE_CHOOSER_ACTION_SAVE,          FILE_NAME,  FALSE },
-      { "/GtkFileChooser/black_box/set_filename/save/focus",            GTK_FILE_CHOOSER_ACTION_SAVE,          FILE_NAME,  TRUE  },
-      { "/GtkFileChooser/black_box/set_filename/select_folder/no_focus", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,        FOLDER_NAME,FALSE },
-      { "/GtkFileChooser/black_box/set_filename/select_folder/focus",   GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FOLDER_NAME,TRUE  },
-      { "/GtkFileChooser/black_box/set_filename/create_folder/no_focus", GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,        FOLDER_NAME,FALSE },
-      { "/GtkFileChooser/black_box/set_filename/create_folder/focus",   GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, FOLDER_NAME,TRUE  },
-    };
-  int i;
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++)
-    g_test_add_data_func (tests[i].test_name, &tests[i], test_black_box_set_filename);
-}
-
-static void
-setup_set_current_name_tests (void)
-{
-  static TestSetCurrentNameSetup tests[] =
-    {
-      { "/GtkFileChooser/black_box/set_current_name/save/no_focus",         GTK_FILE_CHOOSER_ACTION_SAVE,          CURRENT_NAME,        FALSE },
-      { "/GtkFileChooser/black_box/set_current_name/save/focus",            GTK_FILE_CHOOSER_ACTION_SAVE,          CURRENT_NAME,        TRUE  },
-      { "/GtkFileChooser/black_box/set_current_name/create_folder/no_focus", GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, CURRENT_NAME_FOLDER, FALSE },
-      { "/GtkFileChooser/black_box/set_current_name/create_folder/focus",    GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, CURRENT_NAME_FOLDER, TRUE  },
-    };
-  int i;
-
-  for (i = 0; i < G_N_ELEMENTS (tests); i++)
-    g_test_add_data_func (tests[i].test_name, &tests[i], test_black_box_set_current_name);
-}
-#endif
-
-typedef struct
-{
-  const char *shortname;
-  GtkFileChooserAction action;
-  const char *initial_current_folder;
-  const char *initial_filename;
-  gboolean open_dialog;
-  enum {
-    BUTTON,
-    DIALOG
-  } what_to_tweak;
-  const char *tweak_current_folder;
-  const char *tweak_filename;
-  gint dialog_response;
-  gboolean unselect_all;
-  const char *final_current_folder;
-  const char *final_filename;
-} FileChooserButtonTest;
-
-static char *
-make_button_test_name (FileChooserButtonTest *t)
-{
-  return g_strdup_printf ("/GtkFileChooserButton/%s", t->shortname);
-#if 0
-  GString *s = g_string_new ("/GtkFileChooserButton");
-
-  g_string_append_printf (s, "/%s/%s/%s/%s",
-                         get_action_name (t->action),
-                         t->initial_current_folder ? "set_initial_folder" : "no_default_folder",
-                         t->initial_filename ? "set_initial_filename" : "no_initial_filename",
-                         t->open_dialog ? "open_dialog" : "no_dialog");
-
-  if (t->tweak_current_folder)
-    g_string_append (s, "/tweak_current_folder");
-
-  if (t->tweak_filename)
-    g_string_append (s, "/tweak_filename");
-
-  if (t->open_dialog)
-    g_string_append_printf (s, "/%s",
-                           t->dialog_response == GTK_RESPONSE_ACCEPT ? "accept" : "cancel");
-
-  if (t->final_current_folder)
-    g_string_append (s, "/final_current_folder");
-
-  if (t->final_filename)
-    g_string_append (s, "/final_filename");
-
-  return g_string_free (s, FALSE);
-#endif
-}
-
-static gboolean
-sleep_timeout_cb (gpointer data)
-{
-  gtk_main_quit ();
-  return FALSE;
-}
-
-static void
-sleep_in_main_loop (void)
-{
-  guint timeout_id;
-
-  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, 250, sleep_timeout_cb, NULL, NULL);
-  gtk_main ();
-  g_source_remove (timeout_id);
-}
-
-static void
-build_children_list (GtkWidget *widget, gpointer data)
-{
-  GList **list;
-
-  list = data;
-  *list = g_list_prepend (*list, widget);
-}
-
-static GtkWidget *
-find_child_widget_with_atk_role (GtkWidget *widget, AtkRole role)
-{
-  AtkObject *accessible;
-  AtkRole a_role;
-
-  accessible = gtk_widget_get_accessible (widget);
-  a_role = atk_object_get_role (accessible);
-
-  if (a_role == role)
-    return widget;
-  else
-    {
-      GtkWidget *found_child;
-
-      found_child = NULL;
-
-      if (GTK_IS_CONTAINER (widget))
-       {
-         GList *children;
-         GList *l;
-
-         children = NULL;
-         gtk_container_forall (GTK_CONTAINER (widget), build_children_list, &children);
-
-         l = children;
-
-         while (l && !found_child)
-           {
-             GtkWidget *child;
-
-             child = GTK_WIDGET (l->data);
-
-             found_child = find_child_widget_with_atk_role (child, role);
-
-             l = l->next;
-           }
-
-         g_list_free (children);
-       }
-
-      return found_child;
-    }
-}
-
-static const char *
-get_atk_name_for_filechooser_button (GtkFileChooserButton *button)
-{
-  GtkFileChooserAction action;
-  GtkWidget *widget;
-  AtkObject *accessible;
-
-  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button));
-  g_assert (action == GTK_FILE_CHOOSER_ACTION_OPEN || action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
-
-  if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
-    widget = find_child_widget_with_atk_role (GTK_WIDGET (button), ATK_ROLE_PUSH_BUTTON);
-  else
-    widget = find_child_widget_with_atk_role (GTK_WIDGET (button), ATK_ROLE_COMBO_BOX);
-
-  accessible = gtk_widget_get_accessible (widget);
-  return atk_object_get_name (accessible);
-}
-
-static void
-check_that_basename_is_shown (GtkFileChooserButton *button, const char *expected_filename)
-{
-  GtkFileChooserAction action;
-  const char *name_on_button;
-  char *expected_basename;
-
-  name_on_button = get_atk_name_for_filechooser_button (button);
-
-  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button));
-  g_assert (action == GTK_FILE_CHOOSER_ACTION_OPEN || action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
-
-  if (expected_filename)
-    expected_basename = g_path_get_basename (expected_filename);
-  else
-    expected_basename = NULL;
-
-  if (expected_basename)
-    g_assert_cmpstr (expected_basename, ==, name_on_button);
-  else
-    g_assert_cmpstr (name_on_button, ==, "(None)"); /* see gtkfilechooserbutton.c:FALLBACK_DISPLAY_NAME */ /* FIXME: how do we translate this? */
-
-  g_free (expected_basename);
-}
-
-static const char *
-get_expected_shown_filename (GtkFileChooserAction action, const char *folder_name, const char *filename)
-{
-  if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
-    {
-      if (filename)
-       return filename;
-      else
-       return folder_name;
-    }
-  else
-    return filename;
-}
-
-static GtkWidget *
-get_file_chooser_dialog_from_button (GtkFileChooserButton *button)
-{
-  GtkWidget *fc_dialog;
-
-  /* Give me the internal dialog, damnit */
-  fc_dialog = g_object_get_qdata (G_OBJECT (button), g_quark_from_static_string ("gtk-file-chooser-delegate"));
-  g_assert (GTK_IS_FILE_CHOOSER (fc_dialog));
-  g_assert (GTK_IS_DIALOG (fc_dialog));
-
-  return fc_dialog;
-}
-
-typedef struct {
-  GtkWidget *window;
-  GtkWidget *fc_button;
-} WindowAndButton;
-
-static WindowAndButton
-create_window_and_file_chooser_button (GtkFileChooserAction action)
-{
-  WindowAndButton w;
-
-  w.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
-  w.fc_button = gtk_file_chooser_button_new (action == GTK_FILE_CHOOSER_ACTION_OPEN ? "Select a file" : "Select a folder",
-                                            action);
-  gtk_container_add (GTK_CONTAINER (w.window), w.fc_button);
-
-  return w;
-}
-
-typedef struct
-{
-  GObject *object;
-  GHashTable *signals;
-  gboolean in_main_loop;
-} SignalWatcher;
-
-typedef struct
-{
-  SignalWatcher *watcher;
-  char *signal_name;
-  gulong id;
-  gboolean emitted;
-} SignalConnection;
-
-static SignalWatcher *
-signal_watcher_new (GObject *object)
-{
-  SignalWatcher *watcher = g_new0 (SignalWatcher, 1);
-
-  watcher->object = g_object_ref (object);
-  watcher->signals = g_hash_table_new (g_str_hash, g_str_equal);
-
-  return watcher;
-}
-
-static void
-dummy_callback (GObject *object)
-{
-  /* nothing */
-}
-
-static void
-marshal_notify_cb (gpointer data, GClosure *closure)
-{
-  if (data)
-    {
-      SignalConnection *conn;
-
-      conn = data;
-      conn->emitted = TRUE;
-
-      if (conn->watcher->in_main_loop)
-       {
-         gtk_main_quit ();
-         conn->watcher->in_main_loop = FALSE;
-       }
-    }
-}
-
-static void
-signal_watcher_watch_signal (SignalWatcher *watcher, const char *signal_name)
-{
-  SignalConnection *conn;
-
-  conn = g_hash_table_lookup (watcher->signals, signal_name);
-  if (!conn)
-    {
-      GClosure *closure;
-
-      conn = g_new0 (SignalConnection, 1);
-      conn->watcher = watcher;
-      conn->signal_name = g_strdup (signal_name);
-
-      closure = g_cclosure_new (G_CALLBACK (dummy_callback), NULL, NULL);
-      g_closure_add_marshal_guards (closure, conn, marshal_notify_cb, NULL, marshal_notify_cb);
-      conn->id = g_signal_connect_closure (watcher->object, signal_name, closure, FALSE);
-      conn->emitted = FALSE;
-
-      g_hash_table_insert (watcher->signals, conn->signal_name, conn);
-    }
-  else
-    conn->emitted = FALSE;
-}
-
-static gboolean
-signal_watcher_expect (SignalWatcher *watcher, const char *signal_name, char *unused_description)
-{
-  SignalConnection *conn;
-  gboolean emitted;
-
-  conn = g_hash_table_lookup (watcher->signals, signal_name);
-  g_assert (conn != NULL);
-
-  if (!conn->emitted)
-    {
-      guint timeout_id;
-      
-      timeout_id = gdk_threads_add_timeout_full (G_MAXINT, 1000, sleep_timeout_cb, NULL, NULL);
-
-      watcher->in_main_loop = TRUE;
-      gtk_main ();
-      watcher->in_main_loop = FALSE;
-
-      g_source_remove (timeout_id);
-    }
-
-  emitted = conn->emitted;
-  conn->emitted = FALSE;
-
-  return emitted;
-}
-
-static void
-destroy_connection (gpointer key, gpointer value, gpointer user_data)
-{
-  SignalConnection *conn;
-
-  conn = value;
-  g_signal_handler_disconnect (conn->watcher->object, conn->id);
-  g_free (conn->signal_name);
-  g_free (conn);
-}
-
-static void
-signal_watcher_destroy (SignalWatcher *watcher)
-{
-  g_hash_table_foreach (watcher->signals, destroy_connection, NULL);
-  g_hash_table_destroy (watcher->signals);
-  g_object_unref (watcher->object);
-  g_free (watcher);
-}
-
-static void
-test_file_chooser_button_with_response (const FileChooserButtonTest *setup, gint dialog_response)
-{
-  WindowAndButton w;
-  SignalWatcher *watcher;
-  GtkWidget *fc_dialog = NULL;
-  int iterations;
-  int i;
-
-  w = create_window_and_file_chooser_button (setup->action);
-
-  watcher = signal_watcher_new (G_OBJECT (w.fc_button));
-  signal_watcher_watch_signal (watcher, "current-folder-changed");
-  signal_watcher_watch_signal (watcher, "selection-changed");
-
-  if (setup->initial_current_folder)
-    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w.fc_button), setup->initial_current_folder);
-
-  if (setup->initial_filename)
-    gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (w.fc_button), setup->initial_filename);
-
-  gtk_widget_show_all (w.window);
-  wait_for_idle ();
-
-  if (setup->initial_current_folder)
-    g_assert (signal_watcher_expect (watcher, "current-folder-changed", "initial current folder"));
-
-  if (setup->initial_filename)
-    g_assert (signal_watcher_expect (watcher, "selection-changed", "initial filename"));
-
-  check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button),
-                               get_expected_shown_filename (setup->action, setup->initial_current_folder, setup->initial_filename));
-
-  /* If there is a dialog to be opened, we actually test going through it a
-   * couple of times.  This ensures that any state that the button frobs for
-   * each appearance of the dialog will make sense.
-   */
-  if (setup->open_dialog)
-    iterations = 2;
-  else
-    iterations = 1;
-
-  for (i = 0; i < iterations; i++)
-    {
-      GtkFileChooser *chooser_to_tweak;
-
-      if (setup->open_dialog)
-       {
-         GList *children;
-
-         /* Hack our way into the file chooser button; get its GtkButton child and click it */
-         children = gtk_container_get_children (GTK_CONTAINER (w.fc_button));
-         g_assert (children && GTK_IS_BUTTON (children->data));
-         gtk_button_clicked (GTK_BUTTON (children->data));
-         g_list_free (children);
-
-         wait_for_idle ();
-
-         fc_dialog = get_file_chooser_dialog_from_button (GTK_FILE_CHOOSER_BUTTON (w.fc_button));
-       }
-
-      if (setup->what_to_tweak == BUTTON)
-       chooser_to_tweak = GTK_FILE_CHOOSER (w.fc_button);
-      else if (setup->what_to_tweak == DIALOG)
-       chooser_to_tweak = GTK_FILE_CHOOSER (fc_dialog);
-      else
-       g_assert_not_reached ();
-
-      /* Okay, now frob the button or its optional dialog */
-
-      if (setup->tweak_current_folder)
-       {
-         if (setup->what_to_tweak == BUTTON)
-           signal_watcher_watch_signal (watcher, "current-folder-changed");
-
-         gtk_file_chooser_set_current_folder (chooser_to_tweak, setup->tweak_current_folder);
-
-         if (setup->what_to_tweak == BUTTON)
-           g_assert (signal_watcher_expect (watcher, "current-folder-changed", "tweak current folder in button"));
-       }
-
-      if (setup->tweak_filename)
-       {
-         if (setup->what_to_tweak == BUTTON)
-           signal_watcher_watch_signal (watcher, "selection-changed");
-
-         gtk_file_chooser_select_filename (chooser_to_tweak, setup->tweak_filename);
-
-         if (setup->what_to_tweak == BUTTON)
-           g_assert (signal_watcher_expect (watcher, "selection-changed", "tweak filename in button"));
-       }
-
-      if (setup->unselect_all)
-       {
-         if (setup->what_to_tweak == BUTTON)
-           signal_watcher_watch_signal (watcher, "selection-changed");
-
-         gtk_file_chooser_unselect_all (chooser_to_tweak);
-
-         if (setup->what_to_tweak == BUTTON)
-           g_assert (signal_watcher_expect (watcher, "selection-changed", "tweak unselect_all in button"));
-       }
-
-      wait_for_idle ();
-
-      if (setup->open_dialog)
-       {
-         gtk_dialog_response (GTK_DIALOG (fc_dialog), dialog_response);
-         wait_for_idle ();
-
-         gtk_window_resize (GTK_WINDOW (fc_dialog), 500, 500);
-       }
-
-      if (setup->final_current_folder)
-       {
-         char *folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (w.fc_button));
-
-         g_assert_cmpstr (folder, ==, setup->final_current_folder);
-         g_free (folder);
-       }
-
-      if (setup->final_filename)
-       {
-         char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (w.fc_button));
-
-         g_assert_cmpstr (filename, ==, setup->final_filename);
-         g_free (filename);
-       }
-
-      check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button),
-                                   get_expected_shown_filename (setup->action, setup->final_current_folder, setup->final_filename));
-    }
-
-  signal_watcher_destroy (watcher);
-  gtk_widget_destroy (w.window);
-}
-
-static void
-test_file_chooser_button (gconstpointer data)
-{
-  const FileChooserButtonTest *setup = data;
-
-  test_file_chooser_button_with_response (setup, setup->dialog_response);
-
-  if (setup->open_dialog && setup->dialog_response == GTK_RESPONSE_CANCEL)
-    {
-      /* Runs the test again, with DELETE_EVENT (as if the user closed the
-       * dialog instead of using the Cancel button), since the button misbehaved
-       * in that case sometimes.
-       */
-      test_file_chooser_button_with_response (setup, GTK_RESPONSE_DELETE_EVENT);
-    }
-}
-
-static int
-find_accessible_action_num (AtkObject *object, const char *action_name)
-{
-  AtkAction *action_a;
-  int num_actions;
-  int i;
-
-  action_a = ATK_ACTION (object);
-
-  num_actions = atk_action_get_n_actions (action_a);
-
-  for (i = 0; i < num_actions; i++)
-    if (strcmp (atk_action_get_name (action_a, i), action_name) == 0)
-      return i;
-
-  return -1;
-}
-
-static void
-do_accessible_action (AtkObject *object, const char *action_name)
-{
-  int action_num;
-
-  action_num = find_accessible_action_num (object, action_name);
-  g_assert (action_num != -1);
-
-  atk_action_do_action (ATK_ACTION (object), action_num);
-}
-
-static void
-test_file_chooser_button_combo_box_1 (void)
-{
-  WindowAndButton w;
-  GtkWidget *combo_box;
-  AtkObject *combo_box_a;
-  AtkObject *menu_a;
-  int num_items;
-  int other_index;
-  AtkObject *item_a;
-  GtkWidget *fc_dialog;
-
-  w = create_window_and_file_chooser_button (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
-
-  gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (w.fc_button), FOLDER_NAME);
-
-  gtk_widget_show_all (w.window);
-
-  /* Get the accessible for the combo box */
-
-  combo_box = find_child_widget_with_atk_role (GTK_WIDGET (w.fc_button), ATK_ROLE_COMBO_BOX);
-  combo_box_a = gtk_widget_get_accessible (combo_box);
-
-  /* Press the combo box to bring up the menu */
-
-  do_accessible_action (combo_box_a, "press");
-  sleep_in_main_loop (); /* have to wait because bringing up the menu is asynchronous... */
-
-  /* Get the menu from the combo box; it's the first child */
-
-  menu_a = atk_object_ref_accessible_child (combo_box_a, 0);
-  g_assert (atk_object_get_role (menu_a) == ATK_ROLE_MENU);
-
-  /* Check that the last item in the menu is the "Other…" one */
-
-  num_items = atk_object_get_n_accessible_children (menu_a);
-  g_assert (num_items > 0);
-
-  other_index = num_items - 1;
-
-  item_a = atk_object_ref_accessible_child (menu_a, other_index);
-  g_assert_cmpstr (atk_object_get_name (item_a), ==, "Other…");  /* FIXME: how do we translate this? */
-
-  /* Activate the item */
-
-  do_accessible_action (item_a, "click");
-
-  /* Cancel the dialog */
-
-  sleep_in_main_loop ();
-  fc_dialog = get_file_chooser_dialog_from_button (GTK_FILE_CHOOSER_BUTTON (w.fc_button));
-
-  gtk_dialog_response (GTK_DIALOG (fc_dialog), GTK_RESPONSE_CANCEL);
-
-  /* Now check the selection in the combo box */
-  check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button), FOLDER_NAME);
-
-  gtk_widget_destroy (w.window);
-}
-
-static void
-setup_file_chooser_button_combo_box_tests (void)
-{
-  g_test_add_func ("/GtkFileChooserButton/combo_box-1", test_file_chooser_button_combo_box_1);
-}
-
-static FileChooserButtonTest button_tests[] =
-  {
-    /* OPEN tests without dialog */
-
-    {
-      "open-1",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-2",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
-    },
-    {
-      "open-3",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME,               /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
-    },
-    {
-      "open-4",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME_2,             /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME_2              /* final_filename */
-    },
-    {
-      "open-5",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-6",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      FOLDER_NAME_2,           /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME_2,           /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-
-    /* SELECT_FOLDER tests without dialog */
-
-    {
-      "select-folder-1",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-2",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
-    },
-    {
-      "select-folder-3",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME_2            /* final_filename */
-    },
-    {
-      "select-folder-4",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
-    },
-    {
-      "select-folder-5",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-6",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      FOLDER_NAME_2,           /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME_2            /* final_filename */
-    },
-    {
-      "select-folder-7",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      FOLDER_NAME_2,           /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME_2,           /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-8",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      0,                       /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME_2            /* final_filename */
-    },
-
-    /* OPEN tests with dialog, cancelled
-     *
-     * Test names are "open-dialog-cancel-A-B", where A and B can be:
-     *
-     *   A:
-     *      ni - no initial filename
-     *       i - initial filename
-     *      nf - no initial folder
-     *       f - initial folder
-     *
-     *   B:
-     *      nt - no tweaks
-     *       b - tweak button
-     *       d - tweak dialog
-     */
-
-    {
-      "open-dialog-cancel-ni-nt",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-dialog-cancel-ni-b",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME,               /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
-    },
-    {
-      "open-dialog-cancel-ni-d",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME,               /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-dialog-cancel-i-nt",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
-    },
-    {
-      "open-dialog-cancel-i-b",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME_2,             /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME_2              /* final_filename */
-    },
-    {
-      "open-dialog-cancel-i-d",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME_2,             /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
-    },
-    {
-      "open-dialog-cancel-nf-nt",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-dialog-cancel-nf-b",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      FOLDER_NAME,             /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-dialog-cancel-nf-d",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      FOLDER_NAME,             /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-dialog-cancel-f-nt",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-dialog-cancel-f-b",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      FOLDER_NAME_2,           /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME_2,           /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "open-dialog-cancel-f-d",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      FOLDER_NAME_2,           /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-
-    /* SELECT_FOLDER tests with dialog, cancelled */
-
-    {
-      "select-folder-dialog-cancel-ni-nt",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-ni-b",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME,             /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-ni-d",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME,             /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-i-nt",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-i-b",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME_2            /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-i-d",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-nf-nt",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-nf-b",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      FOLDER_NAME,             /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-nf-d",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      FOLDER_NAME,             /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-f-nt",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-f-nt-2",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-f-b",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      FOLDER_NAME_2,           /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME_2,           /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-f-b-2",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME_2            /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-f-d",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      FOLDER_NAME_2,           /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "select-folder-dialog-cancel-f-d-2",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      DIALOG,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      GTK_RESPONSE_CANCEL,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      FOLDER_NAME,             /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-
-    /* OPEN tests with dialog */
-
-    {
-      "open-dialog-1",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME,               /* tweak_filename */
-      GTK_RESPONSE_ACCEPT,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
-    },
-    {
-      "open-dialog-2",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_ACCEPT,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
-    },
-    {
-      "open-dialog-3",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME_2,             /* tweak_filename */
-      GTK_RESPONSE_ACCEPT,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME_2              /* final_filename */
-    },
-    {
-      "open-dialog-4",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME,               /* tweak_filename */
-      GTK_RESPONSE_ACCEPT,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FILE_NAME                        /* final_filename */
-    },
-
-    /* SELECT_FOLDER tests with dialog */
-
-    {
-      "select-folder-dialog-1",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_ACCEPT,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
-    },
-    {
-      "select-folder-dialog-2",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      GTK_RESPONSE_ACCEPT,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME              /* final_filename */
-    },
-    {
-      "select-folder-dialog-3",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      GTK_RESPONSE_ACCEPT,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME_2            /* final_filename */
-    },
-    {
-      "select-folder-dialog-4",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      FOLDER_NAME,             /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      TRUE,                    /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      GTK_RESPONSE_ACCEPT,     /* dialog_response */
-      FALSE,                   /* unselect_all */
-      NULL,                    /* final_current_folder */
-      FOLDER_NAME_2            /* final_filename */
-    },
-
-    /* Unselection tests */
-    {
-      "unselect-all-1",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      TRUE,                    /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "unselect-all-2",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      TRUE,                    /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "unselect-all-3",
-      GTK_FILE_CHOOSER_ACTION_OPEN,
-      NULL,                    /* initial_current_folder */
-      FILE_NAME,               /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FILE_NAME_2,             /* tweak_filename */
-      0,                       /* dialog_response */
-      TRUE,                    /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "unselect-all-4",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      NULL,                    /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      TRUE,                    /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "unselect-all-5",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      NULL,                    /* tweak_filename */
-      0,                       /* dialog_response */
-      TRUE,                    /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-    {
-      "unselect-all-6",
-      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-      NULL,                    /* initial_current_folder */
-      FOLDER_NAME,             /* initial_filename */
-      FALSE,                   /* open_dialog */
-      BUTTON,                  /* what_to_tweak */
-      NULL,                    /* tweak_current_folder */
-      FOLDER_NAME_2,           /* tweak_filename */
-      0,                       /* dialog_response */
-      TRUE,                    /* unselect_all */
-      NULL,                    /* final_current_folder */
-      NULL                     /* final_filename */
-    },
-
-  };
-
-static void
-setup_file_chooser_button_tests (void)
-{
-  int i;
-
-  for (i = 0; i < G_N_ELEMENTS (button_tests); i++)
-    {
-      char *test_name;
-
-      test_name = make_button_test_name (&button_tests[i]);
-      g_test_add_data_func (test_name, &button_tests[i], test_file_chooser_button);
-      g_free (test_name);
-    }
-
-  setup_file_chooser_button_combo_box_tests ();
-}
-
-#ifdef BROKEN_TESTS
-struct confirm_overwrite_closure {
-  GtkWidget *chooser;
-  GtkWidget *accept_button;
-  gint confirm_overwrite_signal_emitted;
-  gchar *extension;
-};
-
-static GtkFileChooserConfirmation
-confirm_overwrite_cb (GtkFileChooser *chooser, gpointer data)
-{
-  struct confirm_overwrite_closure *closure = data;
-
-  if (g_test_verbose())
-    printf ("bling!\n");
-  closure->confirm_overwrite_signal_emitted += 1;
-
-  return GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME;
-}
-
-static void
-overwrite_response_cb (GtkFileChooser *chooser, gint response, gpointer data)
-{
-  struct confirm_overwrite_closure *closure = data;
-  char *filename;
-
-  if (g_test_verbose())
-    printf ("plong!\n");
-
-  if (response != GTK_RESPONSE_ACCEPT)
-    return;
-
-  filename = gtk_file_chooser_get_filename (chooser);
-
-  if (!g_str_has_suffix (filename, closure->extension))
-    {
-      char *basename;
-
-      basename = g_path_get_basename (filename);
-      g_free (filename);
-
-      filename = g_strconcat (basename, closure->extension, NULL);
-      gtk_file_chooser_set_current_name (chooser, filename);
-
-      g_signal_stop_emission_by_name (chooser, "response");
-      gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
-    }
-}
-
-static gboolean
-confirm_overwrite_timeout_cb (gpointer data)
-{
-  struct confirm_overwrite_closure *closure;
-
-  closure = data;
-  gtk_button_clicked (GTK_BUTTON (closure->accept_button));
-
-  return FALSE;
-}
-
-/* http://bugzilla.gnome.org/show_bug.cgi?id=347883 */
-static gboolean
-test_confirm_overwrite_for_path (const char *path, gboolean append_extension)
-{
-  gboolean passed;
-  struct confirm_overwrite_closure closure;
-  char *filename;
-  guint timeout_id;
-
-  passed = TRUE;
-
-  closure.extension = NULL;
-  closure.confirm_overwrite_signal_emitted = 0;
-  closure.chooser = gtk_file_chooser_dialog_new ("hello", NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
-                                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                                NULL);
-  closure.accept_button = gtk_dialog_add_button (GTK_DIALOG (closure.chooser),
-                                                 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT);
-  gtk_dialog_set_default_response (GTK_DIALOG (closure.chooser), GTK_RESPONSE_ACCEPT);
-
-  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (closure.chooser), TRUE);
-
-  g_signal_connect (closure.chooser, "confirm-overwrite",
-                   G_CALLBACK (confirm_overwrite_cb), &closure);
-
-  if (append_extension)
-    {
-      char *extension;
-
-      filename = g_path_get_dirname (path);
-      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (closure.chooser), filename);
-      g_free (filename);
-
-      filename = g_path_get_basename (path);
-      extension = strchr (filename, '.');
-
-      if (extension)
-        {
-          closure.extension = g_strdup (extension);
-          *extension = '\0';
-        }
-
-      gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (closure.chooser), filename);
-      g_free (filename);
-
-      g_signal_connect (closure.chooser, "response",
-                        G_CALLBACK (overwrite_response_cb), &closure);
-    }
-  else
-    {
-      gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (closure.chooser), path);
-    }
-
-  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, confirm_overwrite_timeout_cb, &closure, NULL);
-  gtk_dialog_run (GTK_DIALOG (closure.chooser));
-  g_source_remove (timeout_id);
-
-  filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (closure.chooser));
-  passed = passed && filename && (strcmp (filename, path) == 0);
-  g_free (filename);
-
-  gtk_widget_destroy (closure.chooser);
-
-  passed = passed && (1 == closure.confirm_overwrite_signal_emitted);
-
-  log_test (passed, "Confirm overwrite for %s", path);
-
-  return passed;
-}
-
-static void
-test_confirm_overwrite (void)
-{
-  gboolean passed = TRUE;
-
-  /* first test for a file we know will always exist */
-  passed = passed && test_confirm_overwrite_for_path ("/etc/passwd", FALSE);
-  g_assert (passed);
-  passed = passed && test_confirm_overwrite_for_path ("/etc/resolv.conf", TRUE);
-  g_assert (passed);
-}
-#endif
-
-static const GtkFileChooserAction open_actions[] = {
-  GTK_FILE_CHOOSER_ACTION_OPEN,
-  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
-};
-
-static const GtkFileChooserAction save_actions[] = {
-  GTK_FILE_CHOOSER_ACTION_SAVE,
-  GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
-};
-
-
-#ifdef BROKEN_TESTS
-static gboolean
-has_action (const GtkFileChooserAction *actions,
-           int n_actions,
-           GtkFileChooserAction sought_action)
-{
-  int i;
-
-  for (i = 0; i < n_actions; i++)
-    if (actions[i] == sought_action)
-      return TRUE;
-
-  return FALSE;
-}
-
-static GtkFileChooserDefault *
-get_impl_from_dialog (GtkWidget *dialog)
-{
-  GtkFileChooserDialog *d;
-  GtkFileChooserDialogPrivate *dialog_priv;
-  GtkFileChooserWidget *chooser_widget;
-  GtkFileChooserWidgetPrivate *widget_priv;
-  GtkFileChooserDefault *impl;
-
-  d = GTK_FILE_CHOOSER_DIALOG (dialog);
-  dialog_priv = d->priv;
-  chooser_widget = GTK_FILE_CHOOSER_WIDGET (dialog_priv->widget);
-  if (!chooser_widget)
-    g_error ("BUG: dialog_priv->widget is not a GtkFileChooserWidget");
-
-  widget_priv = chooser_widget->priv;
-  impl = (GtkFileChooserDefault *) (widget_priv->impl);
-  if (!impl)
-    g_error ("BUG: widget_priv->impl is not a GtkFileChooserDefault");
-
-  return impl;
-}
-
-static gboolean
-test_widgets_for_current_action (GtkFileChooserDialog *dialog,
-                                GtkFileChooserAction  expected_action)
-{
-  GtkFileChooserDefault *impl;
-  gboolean passed;
-
-  if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) != expected_action)
-    return FALSE;
-
-  impl = get_impl_from_dialog (GTK_WIDGET (dialog));
-
-  g_assert (impl->action == expected_action);
-
-  passed = TRUE;
-
-  /* OPEN implies that the "new folder" button is hidden; otherwise it is shown */
-  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
-    passed = passed && !gtk_widget_get_visible (impl->browse_new_folder_button);
-  else
-    passed = passed && gtk_widget_get_visible (impl->browse_new_folder_button);
-
-  /* Check that the widgets are present/visible or not */
-  if (has_action (open_actions, G_N_ELEMENTS (open_actions), impl->action))
-    {
-      passed = passed && (impl->save_widgets == NULL
-                         && (impl->location_mode == LOCATION_MODE_PATH_BAR
-                             ? impl->location_entry == NULL
-                             : impl->location_entry != NULL)
-                         && impl->save_folder_label == NULL
-                         && impl->save_folder_combo == NULL
-                         && impl->save_expander == NULL
-                         && GTK_IS_CONTAINER (impl->browse_widgets) && gtk_widget_is_drawable (impl->browse_widgets));
-    }
-  else if (has_action (save_actions, G_N_ELEMENTS (save_actions), impl->action))
-    {
-      /* FIXME: we can't use GTK_IS_FILE_CHOOSER_ENTRY() because it uses
-       * _gtk_file_chooser_entry_get_type(), which is a non-exported symbol.
-       * So, we just test impl->location_entry for being non-NULL
-       */
-      passed = passed && (GTK_IS_CONTAINER (impl->save_widgets) && gtk_widget_is_drawable (impl->save_widgets)
-                         && impl->location_entry != NULL && gtk_widget_is_drawable (impl->location_entry)
-                         && GTK_IS_LABEL (impl->save_folder_label) && gtk_widget_is_drawable (impl->save_folder_label)
-                         && GTK_IS_COMBO_BOX (impl->save_folder_combo) && gtk_widget_is_drawable (impl->save_folder_combo)
-                         && GTK_IS_EXPANDER (impl->save_expander) && gtk_widget_is_drawable (impl->save_expander)
-                         && GTK_IS_CONTAINER (impl->browse_widgets));
-
-      /* FIXME: we are in a SAVE mode; test the visibility and sensitivity of
-       * the children that change depending on the state of the expander.
-       */
-    }
-  else
-    {
-      g_error ("BAD TEST: test_widgets_for_current_action() doesn't know about %s", get_action_name (impl->action));
-      passed = FALSE;
-    }
-
-  return passed;
-}
-
-typedef gboolean (* ForeachActionCallback) (GtkFileChooserDialog *dialog,
-                                           GtkFileChooserAction  action,
-                                           gpointer              user_data);
-
-static gboolean
-foreach_action (GtkFileChooserDialog *dialog,
-               ForeachActionCallback callback,
-               gpointer              user_data)
-{
-  GEnumClass *enum_class;
-  int i;
-
-  enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION);
-  if (!enum_class)
-    g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION");
-
-  for (i = 0; i < enum_class->n_values; i++)
-    {
-      GEnumValue *enum_value;
-      GtkFileChooserAction action;
-      gboolean passed;
-
-      enum_value = enum_class->values + i;
-      action = enum_value->value;
-
-      passed = (* callback) (dialog, action, user_data);
-      if (!passed)
-       return FALSE;
-    }
-
-  return TRUE;
-}
-
-struct action_closure {
-  GtkFileChooserAction from_action;
-};
-
-static gboolean
-switch_from_to_action_cb (GtkFileChooserDialog *dialog,
-                         GtkFileChooserAction  action,
-                         gpointer              user_data)
-{
-  struct action_closure *closure;
-  gboolean passed;
-
-  closure = user_data;
-
-  gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), closure->from_action);
-
-  passed = test_widgets_for_current_action (dialog, closure->from_action);
-  log_test (passed, "switch_from_to_action_cb(): reset to action %s", get_action_name (closure->from_action));
-  if (!passed)
-    return FALSE;
-
-  gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), action);
-
-  passed = test_widgets_for_current_action (dialog, action);
-  log_test (passed, "switch_from_to_action_cb(): transition from %s to %s",
-           get_action_name (closure->from_action),
-           get_action_name (action));
-  return passed;
-}
-
-static gboolean
-switch_from_action_cb (GtkFileChooserDialog *dialog,
-                      GtkFileChooserAction  action,
-                      gpointer              user_data)
-{
-  struct action_closure closure;
-
-  closure.from_action = action;
-
-  return foreach_action (dialog, switch_from_to_action_cb, &closure);
-}
-
-static void
-test_action_widgets (void)
-{
-  GtkWidget *dialog;
-  GtkFileChooserAction action;
-  gboolean passed;
-
-  dialog = gtk_file_chooser_dialog_new ("Test file chooser",
-                                       NULL,
-                                       GTK_FILE_CHOOSER_ACTION_OPEN,
-                                       GTK_STOCK_CANCEL,
-                                       GTK_RESPONSE_CANCEL,
-                                       GTK_STOCK_OK,
-                                       GTK_RESPONSE_ACCEPT,
-                                       NULL);
-  gtk_widget_show_now (dialog);
-
-  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog));
-
-  passed = test_widgets_for_current_action (GTK_FILE_CHOOSER_DIALOG (dialog), action);
-  log_test (passed, "test_action_widgets(): widgets for initial action %s", get_action_name (action));
-  g_assert (passed);
-
-  passed = foreach_action (GTK_FILE_CHOOSER_DIALOG (dialog), switch_from_action_cb, NULL);
-  log_test (passed, "test_action_widgets(): all transitions through property change");
-  g_assert (passed);
-
-  gtk_widget_destroy (dialog);
-}
-#endif
-
-#ifdef BROKEN_TESTS
-static gboolean
-test_reload_sequence (gboolean set_folder_before_map)
-{
-  GtkWidget *dialog;
-  GtkFileChooserDefault *impl;
-  gboolean passed;
-  char *folder;
-  char *current_working_dir;
-
-  passed = TRUE;
-
-  current_working_dir = g_get_current_dir ();
-
-  dialog = gtk_file_chooser_dialog_new ("Test file chooser",
-                                       NULL,
-                                       GTK_FILE_CHOOSER_ACTION_OPEN,
-                                       GTK_STOCK_CANCEL,
-                                       GTK_RESPONSE_CANCEL,
-                                       GTK_STOCK_OK,
-                                       GTK_RESPONSE_ACCEPT,
-                                       NULL);
-  impl = get_impl_from_dialog (dialog);
-
-  if (set_folder_before_map)
-    {
-      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
-
-      wait_for_idle ();
-
-      passed = passed && (impl->current_folder != NULL
-                         && impl->browse_files_model != NULL
-                         && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
-                         && impl->reload_state == RELOAD_HAS_FOLDER
-                         && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
-                         && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
-                             ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
-                             : TRUE));
-
-      wait_for_idle ();
-
-      folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
-      passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
-      g_free (folder);
-    }
-  else
-    {
-      /* Initially, no folder is not loaded or pending */
-      passed = passed && (impl->current_folder == NULL
-                         && impl->sort_model == NULL
-                         && impl->browse_files_model == NULL
-                         && impl->load_state == LOAD_EMPTY
-                         && impl->reload_state == RELOAD_EMPTY
-                         && impl->load_timeout_id == 0);
-
-      wait_for_idle ();
-
-      folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
-      passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
-    }
-
-  log_test (passed, "test_reload_sequence(): initial status");
-
-  /* After mapping, it is loading some folder, either the one that was explicitly set or the default one */
-
-  gtk_widget_show_now (dialog);
-
-  wait_for_idle ();
-
-  passed = passed && (impl->current_folder != NULL
-                     && impl->browse_files_model != NULL
-                     && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
-                     && impl->reload_state == RELOAD_HAS_FOLDER
-                     && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
-                     && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
-                         ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
-                         : TRUE));
-
-  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
-  if (set_folder_before_map)
-    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
-  else
-    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
-
-  g_free (folder);
-
-  log_test (passed, "test_reload_sequence(): status after map");
-
-  /* Unmap it; we should still have a folder */
-
-  gtk_widget_hide (dialog);
-
-  wait_for_idle ();
-
-  passed = passed && (impl->current_folder != NULL
-                     && impl->browse_files_model != NULL
-                     && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
-                     && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
-                     && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
-                         ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
-                         : TRUE));
-
-  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
-  if (set_folder_before_map)
-    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
-  else
-    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
-
-  g_free (folder);
-
-  log_test (passed, "test_reload_sequence(): status after unmap");
-
-  /* Map it again! */
-
-  gtk_widget_show_now (dialog);
-
-  wait_for_idle ();
-
-  passed = passed && (impl->current_folder != NULL
-                     && impl->browse_files_model != NULL
-                     && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
-                     && impl->reload_state == RELOAD_HAS_FOLDER
-                     && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
-                     && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
-                         ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
-                         : TRUE));
-
-  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
-  if (set_folder_before_map)
-    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
-  else
-    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
-
-  g_free (folder);
-
-  log_test (passed, "test_reload_sequence(): status after re-map");
-
-  gtk_widget_destroy (dialog);
-  g_free (current_working_dir);
-
-  return passed;
-}
-
-static void
-test_reload (void)
-{
-  gboolean passed;
-
-  passed = test_reload_sequence (FALSE);
-  log_test (passed, "test_reload(): create and use the default folder");
-  g_assert (passed);
-
-  passed = test_reload_sequence (TRUE);
-  log_test (passed, "test_reload(): set a folder explicitly before mapping");
-  g_assert (passed);
-}
-
-static gboolean
-test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_dialog, gboolean set_folder_on_dialog)
-{
-  gboolean passed;
-  GtkWidget *window;
-  GtkWidget *button;
-  char *folder;
-  GtkWidget *dialog;
-  char *current_working_dir;
-  gboolean must_have_cwd;
-
-  passed = TRUE;
-
-  current_working_dir = g_get_current_dir ();
-  must_have_cwd = !(use_dialog && set_folder_on_dialog);
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
-  if (use_dialog)
-    {
-      dialog = gtk_file_chooser_dialog_new ("Test", NULL, action,
-                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                           GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                                           NULL);
-      button = gtk_file_chooser_button_new_with_dialog (dialog);
-
-      if (set_folder_on_dialog)
-       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
-    }
-  else
-    {
-      button = gtk_file_chooser_button_new ("Test", action);
-      dialog = NULL; /* keep gcc happy */
-    }
-
-  gtk_container_add (GTK_CONTAINER (window), button);
-
-  /* Pre-map; no folder is set */
-  wait_for_idle ();
-
-  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
-  if (must_have_cwd)
-    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
-  else
-    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
-
-  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, pre-map, %s",
-           get_action_name (action),
-           use_dialog,
-           set_folder_on_dialog,
-           must_have_cwd ? "must have $cwd" : "must have explicit folder");
-
-  /* Map; folder should be set */
-
-  gtk_widget_show_all (window);
-  gtk_widget_show_now (window);
-
-  wait_for_idle ();
-
-  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
-
-  if (must_have_cwd)
-    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
-  else
-    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
-
-  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, mapped, %s",
-           get_action_name (action),
-           use_dialog,
-           set_folder_on_dialog,
-           must_have_cwd ? "must have $cwd" : "must have explicit folder");
-  g_free (folder);
-
-  /* Unmap; folder should be set */
-
-  gtk_widget_hide (window);
-  wait_for_idle ();
-  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
-
-  if (must_have_cwd)
-    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
-  else
-    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
-
-  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, unmapped, %s",
-           get_action_name (action),
-           use_dialog,
-           set_folder_on_dialog,
-           must_have_cwd ? "must have $cwd" : "must have explicit folder");
-  g_free (folder);
-
-  /* Re-map; folder should be set */
-
-  gtk_widget_show_now (window);
-  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
-
-  if (must_have_cwd)
-    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
-  else
-    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
-  wait_for_idle ();
-  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, re-mapped, %s",
-           get_action_name (action),
-           use_dialog,
-           set_folder_on_dialog,
-           must_have_cwd ? "must have $cwd" : "must have explicit folder");
-  g_free (folder);
-
-  g_free (current_working_dir);
-
-  gtk_widget_destroy (window);
-
-  return passed;
-}
-
-static void
-test_button_folder_states (void)
-{
-  /* GtkFileChooserButton only supports OPEN and SELECT_FOLDER */
-  static const GtkFileChooserAction actions_to_test[] = {
-    GTK_FILE_CHOOSER_ACTION_OPEN,
-    GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
-  };
-  gboolean passed;
-  int i;
-
-  passed = TRUE;
-
-  for (i = 0; i < G_N_ELEMENTS (actions_to_test); i++)
-    {
-      passed = passed && test_button_folder_states_for_action (actions_to_test[i], FALSE, FALSE);
-      g_assert (passed);
-      passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, FALSE);
-      g_assert (passed);
-      passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, TRUE);
-      g_assert (passed);
-      log_test (passed, "test_button_folder_states(): action %s", get_action_name (actions_to_test[i]));
-    }
-
-  log_test (passed, "test_button_folder_states(): all supported actions");
-}
-
-static void
-test_folder_switch_and_filters (void)
-{
-  gboolean passed;
-  char *cwd;
-  char *base_dir;
-  GFile *cwd_file;
-  GFile *base_dir_file;
-  GtkWidget *dialog;
-  GtkFileFilter *all_filter;
-  GtkFileFilter *txt_filter;
-  GtkFileChooserDefault *impl;
-
-  passed = TRUE;
-
-  cwd = g_get_current_dir ();
-  base_dir = g_build_filename (cwd, "file-chooser-test-dir", NULL);
-
-  dialog = gtk_file_chooser_dialog_new ("Test", NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
-                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-                                       NULL);
-  impl = get_impl_from_dialog (dialog);
-
-  cwd_file = g_file_new_for_path (cwd);
-  base_dir_file = g_file_new_for_path (base_dir);
-
-  passed = passed && gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
-  g_assert (passed);
-
-  /* All files filter */
-
-  all_filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (all_filter, "All files");
-  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_filter);
-
-  /* *.txt filter */
-
-  txt_filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (all_filter, "*.txt");
-  gtk_file_filter_add_pattern (txt_filter, "*.txt");
-  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
-
-  /* Test filter set */
-
-  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all_filter);
-  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == all_filter);
-  g_assert (passed);
-
-  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
-  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
-  log_test (passed, "test_folder_switch_and_filters(): set and get filter");
-  g_assert (passed);
-
-  gtk_widget_show (dialog);
-
-  /* Test that filter is unchanged when we switch folders */
-
-  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd);
-  sleep_in_main_loop ();
-  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
-  g_assert (passed);
-
-  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
-  sleep_in_main_loop ();
-
-  g_signal_emit_by_name (impl->browse_path_bar, "path-clicked",
-                        cwd_file,
-                        base_dir_file,
-                        FALSE);
-  sleep_in_main_loop ();
-  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
-  log_test (passed, "test_folder_switch_and_filters(): filter after changing folder");
-  g_assert (passed);
-
-  /* cleanups */
-  g_free (cwd);
-  g_free (base_dir);
-  g_object_unref (cwd_file);
-  g_object_unref (base_dir_file);
-
-  gtk_widget_destroy (dialog);
-
-  log_test (passed, "test_folder_switch_and_filters(): all filter tests");
-}
-#endif
-
-int
-main (int    argc,
-      char **argv)
-{
-  /* initialize test program */
-  gtk_test_init (&argc, &argv);
-
-  /* Register tests */
-
-  setup_file_chooser_button_tests ();
-#ifdef BROKEN_TESTS
-  setup_set_filename_tests ();
-  setup_set_current_name_tests ();
-
-  g_test_add_func ("/GtkFileChooser/confirm_overwrite", test_confirm_overwrite);
-  g_test_add_func ("/GtkFileChooser/action_widgets", test_action_widgets);
-  g_test_add_func ("/GtkFileChooser/reload", test_reload);
-  g_test_add_func ("/GtkFileChooser/button_folder_states", test_button_folder_states);
-  g_test_add_func ("/GtkFileChooser/folder_switch_and_filters", test_folder_switch_and_filters);
-#endif
-
-  /* run and check selected tests */
-  return g_test_run();
-}
diff --git a/gtk/tests/filtermodel.c b/gtk/tests/filtermodel.c
deleted file mode 100644 (file)
index dcacf8d..0000000
+++ /dev/null
@@ -1,7147 +0,0 @@
-/* Extensive GtkTreeModelFilter tests.
- * Copyright (C) 2009,2011  Kristian Rietveld  <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-#include <string.h>
-
-#include "treemodel.h"
-#include "gtktreemodelrefcount.h"
-
-/* Left to do:
- *   - Proper coverage checking to see if the unit tests cover
- *     all possible cases.
- *   - Check if the iterator stamp is incremented at the correct times.
- *
- * For more thorough testing:
- *   - Test with randomized models.
- *   - Extensively test a filter model wrapping a sort model,
- *     or a sort model wrapping a filter model by:
- *       # Checking structure.
- *       # Checking for correct signals emissions.
- *       # Checking correct reference counting.
- *       # Tests should be done with the sort and filter model
- *         in various filtering and sorting states.
- */
-
-
-/*
- * Model creation
- */
-
-#define LEVEL_LENGTH 5
-
-static void
-create_tree_store_set_values (GtkTreeStore *store,
-                              GtkTreeIter  *iter,
-                              gboolean      visible)
-{
-  GtkTreePath *path;
-  gchar *path_string;
-
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
-  path_string = gtk_tree_path_to_string (path);
-
-  gtk_tree_store_set (store, iter,
-                      0, path_string,
-                      1, visible,
-                      -1);
-
-  gtk_tree_path_free (path);
-  g_free (path_string);
-}
-
-static void
-create_tree_store_recurse (int           depth,
-                           GtkTreeStore *store,
-                           GtkTreeIter  *parent,
-                           gboolean      visible)
-{
-  int i;
-
-  for (i = 0; i < LEVEL_LENGTH; i++)
-    {
-      GtkTreeIter iter;
-
-      gtk_tree_store_insert (store, &iter, parent, i);
-      create_tree_store_set_values (store, &iter, visible);
-
-      if (depth > 0)
-        create_tree_store_recurse (depth - 1, store, &iter, visible);
-    }
-}
-
-static GtkTreeStore *
-create_tree_store (int      depth,
-                   gboolean visible)
-{
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-
-  create_tree_store_recurse (depth, store, NULL, visible);
-
-  return store;
-}
-
-/*
- * Fixture
- */
-
-typedef struct
-{
-  GtkWidget *tree_view;
-
-  GtkTreeStore *store;
-  GtkTreeModelFilter *filter;
-
-  SignalMonitor *monitor;
-
-  guint block_signals : 1;
-} FilterTest;
-
-
-static void
-filter_test_store_signal (FilterTest *fixture)
-{
-  if (fixture->block_signals)
-    g_signal_stop_emission_by_name (fixture->store, "row-changed");
-}
-
-
-static void
-filter_test_setup_generic (FilterTest    *fixture,
-                           gconstpointer  test_data,
-                           int            depth,
-                           gboolean       empty,
-                           gboolean       unfiltered)
-{
-  const GtkTreePath *vroot = test_data;
-  GtkTreeModel *filter;
-
-  fixture->store = create_tree_store (depth, !empty);
-
-  g_signal_connect_swapped (fixture->store, "row-changed",
-                            G_CALLBACK (filter_test_store_signal), fixture);
-
-  /* Please forgive me for casting const away. */
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
-                                      (GtkTreePath *)vroot);
-  fixture->filter = GTK_TREE_MODEL_FILTER (filter);
-
-  if (!unfiltered)
-    gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
-
-  /* We need a tree view that's listening to get ref counting from that
-   * side.
-   */
-  fixture->tree_view = gtk_tree_view_new_with_model (filter);
-
-  fixture->monitor = signal_monitor_new (filter);
-}
-
-static void
-filter_test_setup_expand_root (FilterTest *fixture)
-{
-  int i;
-  GtkTreePath *path;
-
-  path = gtk_tree_path_new_from_indices (0, -1);
-
-  for (i = 0; i < LEVEL_LENGTH; i++)
-    {
-      gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view),
-                                path, FALSE);
-      gtk_tree_path_next (path);
-    }
-  gtk_tree_path_free (path);
-}
-
-static void
-filter_test_setup (FilterTest    *fixture,
-                   gconstpointer  test_data)
-{
-  filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
-}
-
-static void
-filter_test_setup_empty (FilterTest    *fixture,
-                         gconstpointer  test_data)
-{
-  filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
-}
-
-static void
-filter_test_setup_unfiltered (FilterTest    *fixture,
-                              gconstpointer  test_data)
-{
-  filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
-}
-
-static void
-filter_test_setup_unfiltered_root_expanded (FilterTest    *fixture,
-                                            gconstpointer  test_data)
-{
-  filter_test_setup_unfiltered (fixture, test_data);
-  filter_test_setup_expand_root (fixture);
-}
-
-static void
-filter_test_setup_empty_unfiltered (FilterTest    *fixture,
-                                    gconstpointer  test_data)
-{
-  filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
-}
-
-static void
-filter_test_setup_empty_unfiltered_root_expanded (FilterTest    *fixture,
-                                                  gconstpointer  test_data)
-{
-  filter_test_setup_empty_unfiltered (fixture, test_data);
-  filter_test_setup_expand_root (fixture);
-}
-
-static GtkTreePath *
-strip_virtual_root (GtkTreePath *path,
-                    GtkTreePath *root_path)
-{
-  GtkTreePath *real_path;
-
-  if (root_path)
-    {
-      int j;
-      int depth = gtk_tree_path_get_depth (path);
-      int root_depth = gtk_tree_path_get_depth (root_path);
-
-      real_path = gtk_tree_path_new ();
-
-      for (j = 0; j < depth - root_depth; j++)
-        gtk_tree_path_append_index (real_path,
-                                    gtk_tree_path_get_indices (path)[root_depth + j]);
-    }
-  else
-    real_path = gtk_tree_path_copy (path);
-
-  return real_path;
-}
-
-static int
-count_visible (FilterTest  *fixture,
-               GtkTreePath *store_path)
-{
-  int i;
-  int n_visible = 0;
-  GtkTreeIter iter;
-
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
-                           &iter, store_path);
-
-  for (i = 0; i < LEVEL_LENGTH; i++)
-    {
-      gboolean visible;
-
-      gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
-                          1, &visible,
-                          -1);
-
-      if (visible)
-        n_visible++;
-    }
-
-  return n_visible;
-}
-
-static void
-filter_test_append_refilter_signals_recurse (FilterTest  *fixture,
-                                             GtkTreePath *store_path,
-                                             GtkTreePath *filter_path,
-                                             int          depth,
-                                             GtkTreePath *root_path)
-{
-  int i;
-  int rows_deleted = 0;
-  GtkTreeIter iter;
-
-  gtk_tree_path_down (store_path);
-  gtk_tree_path_down (filter_path);
-
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
-                           &iter, store_path);
-
-  for (i = 0; i < LEVEL_LENGTH; i++)
-    {
-      gboolean visible;
-      GtkTreePath *real_path;
-
-      gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
-                          1, &visible,
-                          -1);
-
-      if (root_path &&
-          (!gtk_tree_path_is_descendant (store_path, root_path)
-           || !gtk_tree_path_compare (store_path, root_path)))
-        {
-          if (!gtk_tree_path_compare (store_path, root_path))
-            {
-              if (depth > 1
-                  && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
-                                                    &iter))
-                {
-                  GtkTreePath *store_copy;
-                  GtkTreePath *filter_copy;
-
-                  store_copy = gtk_tree_path_copy (store_path);
-                  filter_copy = gtk_tree_path_copy (filter_path);
-                  filter_test_append_refilter_signals_recurse (fixture,
-                                                               store_copy,
-                                                               filter_copy,
-                                                               depth - 1,
-                                                               root_path);
-                  gtk_tree_path_free (store_copy);
-                  gtk_tree_path_free (filter_copy);
-                }
-            }
-
-          gtk_tree_path_next (store_path);
-          gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-
-          if (visible)
-            gtk_tree_path_next (filter_path);
-
-          continue;
-        }
-
-      real_path = strip_virtual_root (filter_path, root_path);
-
-      if (visible)
-        {
-          /* This row will be inserted */
-          signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
-                                             real_path);
-
-          if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
-                                             &iter))
-            {
-              signal_monitor_append_signal_path (fixture->monitor,
-                                                 ROW_HAS_CHILD_TOGGLED,
-                                                 real_path);
-
-              if (depth > 1)
-                {
-                  GtkTreePath *store_copy;
-                  GtkTreePath *filter_copy;
-
-                  store_copy = gtk_tree_path_copy (store_path);
-                  filter_copy = gtk_tree_path_copy (filter_path);
-                  filter_test_append_refilter_signals_recurse (fixture,
-                                                               store_copy,
-                                                               filter_copy,
-                                                               depth - 1,
-                                                               root_path);
-                  gtk_tree_path_free (store_copy);
-                  gtk_tree_path_free (filter_copy);
-                }
-              else if (depth == 1)
-                {
-                  GtkTreePath *tmp_path;
-
-                  /* If all child rows are invisible, then the last row to
-                   * become invisible will emit row-has-child-toggled on the
-                   * parent.
-                   */
-
-                  tmp_path = gtk_tree_path_copy (store_path);
-                  gtk_tree_path_append_index (tmp_path, 0);
-
-                  if (count_visible (fixture, tmp_path) == 0)
-                    signal_monitor_append_signal_path (fixture->monitor,
-                                                       ROW_HAS_CHILD_TOGGLED,
-                                                       real_path);
-
-                  gtk_tree_path_free (tmp_path);
-                }
-            }
-
-          gtk_tree_path_next (filter_path);
-        }
-      else
-        {
-          /* This row will be deleted */
-          rows_deleted++;
-          signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
-                                             real_path);
-        }
-
-      gtk_tree_path_free (real_path);
-
-      gtk_tree_path_next (store_path);
-      gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-    }
-
-  if (rows_deleted == LEVEL_LENGTH
-      && gtk_tree_path_get_depth (filter_path) > 1)
-    {
-      GtkTreePath *real_path;
-
-      gtk_tree_path_up (store_path);
-      gtk_tree_path_up (filter_path);
-
-      /* A row-has-child-toggled will be emitted on the parent */
-      if (!root_path
-          || (root_path
-              && gtk_tree_path_is_descendant (store_path, root_path)
-              && gtk_tree_path_compare (store_path, root_path)))
-        {
-          real_path = strip_virtual_root (filter_path, root_path);
-          signal_monitor_append_signal_path (fixture->monitor,
-                                             ROW_HAS_CHILD_TOGGLED,
-                                             real_path);
-
-          gtk_tree_path_free (real_path);
-        }
-    }
-}
-
-static void
-filter_test_append_refilter_signals (FilterTest *fixture,
-                                     int         depth)
-{
-  /* A special function that walks the tree store like the
-   * model validation functions below.
-   */
-  GtkTreePath *path;
-  GtkTreePath *filter_path;
-
-  path = gtk_tree_path_new ();
-  filter_path = gtk_tree_path_new ();
-  filter_test_append_refilter_signals_recurse (fixture,
-                                               path,
-                                               filter_path,
-                                               depth,
-                                               NULL);
-  gtk_tree_path_free (path);
-  gtk_tree_path_free (filter_path);
-}
-
-static void
-filter_test_append_refilter_signals_with_vroot (FilterTest  *fixture,
-                                                int          depth,
-                                                GtkTreePath *root_path)
-{
-  /* A special function that walks the tree store like the
-   * model validation functions below.
-   */
-  GtkTreePath *path;
-  GtkTreePath *filter_path;
-
-  path = gtk_tree_path_new ();
-  filter_path = gtk_tree_path_new ();
-  filter_test_append_refilter_signals_recurse (fixture,
-                                               path,
-                                               filter_path,
-                                               depth,
-                                               root_path);
-  gtk_tree_path_free (path);
-  gtk_tree_path_free (filter_path);
-}
-
-static void
-filter_test_enable_filter (FilterTest *fixture)
-{
-  gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
-  gtk_tree_model_filter_refilter (fixture->filter);
-}
-
-static void
-filter_test_block_signals (FilterTest *fixture)
-{
-  fixture->block_signals = TRUE;
-}
-
-static void
-filter_test_unblock_signals (FilterTest *fixture)
-{
-  fixture->block_signals = FALSE;
-}
-
-static void
-filter_test_teardown (FilterTest    *fixture,
-                      gconstpointer  test_data)
-{
-  signal_monitor_free (fixture->monitor);
-
-  gtk_widget_destroy (fixture->tree_view);
-
-  g_object_unref (fixture->filter);
-  g_object_unref (fixture->store);
-}
-
-/*
- * Model structure validation
- */
-
-static void
-check_filter_model_recurse (FilterTest  *fixture,
-                            GtkTreePath *store_parent_path,
-                            GtkTreePath *filter_parent_path)
-{
-  int i;
-  GtkTreeIter store_iter;
-  GtkTreeIter filter_iter;
-  gboolean store_has_next, filter_has_next;
-
-  gtk_tree_path_down (store_parent_path);
-  gtk_tree_path_down (filter_parent_path);
-
-  store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
-                                            &store_iter, store_parent_path);
-  filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
-                                             &filter_iter, filter_parent_path);
-
-  for (i = 0; i < LEVEL_LENGTH; i++)
-    {
-      gboolean visible;
-
-      g_return_if_fail (store_has_next == TRUE);
-
-      gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
-                          &store_iter,
-                          1, &visible,
-                          -1);
-
-      if (visible)
-        {
-          GtkTreePath *tmp;
-          gchar *filter_str, *store_str;
-
-          g_return_if_fail (filter_has_next == TRUE);
-
-          /* Verify path */
-          tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
-                                         &filter_iter);
-          g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
-
-          /* Verify model content */
-          gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
-                              &store_iter,
-                              0, &store_str,
-                              -1);
-          gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
-                              &filter_iter,
-                              0, &filter_str,
-                              -1);
-
-          g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
-
-          g_free (store_str);
-          g_free (filter_str);
-
-          if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
-                                             &filter_iter))
-            {
-              g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
-
-              check_filter_model_recurse (fixture,
-                                          gtk_tree_path_copy (store_parent_path),
-                                          tmp);
-            }
-          else
-            /* Only when we do not recurse we need to free tmp */
-            gtk_tree_path_free (tmp);
-
-          gtk_tree_path_next (filter_parent_path);
-          filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
-        }
-
-      gtk_tree_path_next (store_parent_path);
-      store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
-    }
-
-  /* Both models should have no more content! */
-  g_return_if_fail (store_has_next == FALSE);
-  g_return_if_fail (filter_has_next == FALSE);
-
-  gtk_tree_path_free (store_parent_path);
-  gtk_tree_path_free (filter_parent_path);
-}
-
-static void
-check_filter_model (FilterTest *fixture)
-{
-  GtkTreePath *path;
-
-  if (fixture->monitor)
-    signal_monitor_assert_is_empty (fixture->monitor);
-
-  path = gtk_tree_path_new ();
-
-  check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
-}
-
-static void
-check_filter_model_with_root (FilterTest  *fixture,
-                              GtkTreePath *path)
-{
-  if (fixture->monitor)
-    signal_monitor_assert_is_empty (fixture->monitor);
-
-  check_filter_model_recurse (fixture,
-                              gtk_tree_path_copy (path),
-                              gtk_tree_path_new ());
-}
-
-/* Helpers */
-
-static void
-check_level_length (GtkTreeModelFilter *filter,
-                    const gchar        *level,
-                    const int           expected_length)
-{
-  if (!level)
-    {
-      int model_length;
-
-      model_length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
-      g_assert_cmpint (model_length, ==, expected_length);
-    }
-  else
-    {
-      int model_length;
-      gboolean retrieved_iter = FALSE;
-      GtkTreeIter iter;
-
-      retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
-                                                            &iter, level);
-      g_return_if_fail (retrieved_iter);
-      model_length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
-      g_assert_cmpint (model_length, ==, expected_length);
-    }
-}
-
-static void
-set_path_visibility (FilterTest  *fixture,
-                     const gchar *path,
-                     gboolean     visible)
-{
-  GtkTreeIter store_iter;
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &store_iter, path);
-  gtk_tree_store_set (fixture->store, &store_iter,
-                      1, visible,
-                      -1);
-}
-
-#if 0
-static void
-insert_path_with_visibility (FilterTest  *fixture,
-                             const gchar *path_string,
-                             gboolean     visible)
-{
-  int position;
-  GtkTreePath *path;
-  GtkTreeIter parent, iter;
-
-  path = gtk_tree_path_new_from_string (path_string);
-  position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
-  gtk_tree_path_up (path);
-
-  if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
-    {
-      gtk_tree_store_insert (fixture->store, &iter, &parent, position);
-      create_tree_store_set_values (fixture->store, &iter, visible);
-    }
-  gtk_tree_path_free (path);
-}
-#endif
-
-/*
- * The actual tests.
- */
-
-static void
-verify_test_suite (FilterTest    *fixture,
-                   gconstpointer  user_data)
-{
-  check_filter_model (fixture);
-}
-
-static void
-verify_test_suite_vroot (FilterTest    *fixture,
-                         gconstpointer  user_data)
-{
-  check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
-}
-
-
-static void
-filled_hide_root_level (FilterTest    *fixture,
-                        gconstpointer  user_data)
-{
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
-  set_path_visibility (fixture, "2", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  set_path_visibility (fixture, "0", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
-  set_path_visibility (fixture, "4", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
-
-
-  /* Hide remaining */
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-
-  set_path_visibility (fixture, "1", FALSE);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
-
-  set_path_visibility (fixture, "3", FALSE);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
-
-  check_filter_model (fixture);
-
-  /* Show some */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
-
-  set_path_visibility (fixture, "1", TRUE);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
-
-  set_path_visibility (fixture, "3", TRUE);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
-
-  check_filter_model (fixture);
-}
-
-static void
-filled_hide_child_levels (FilterTest    *fixture,
-                          gconstpointer  user_data)
-{
-  set_path_visibility (fixture, "0:2", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
-
-  set_path_visibility (fixture, "0:4", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "0:4:3", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "0:4:0", FALSE);
-  set_path_visibility (fixture, "0:4:1", FALSE);
-  set_path_visibility (fixture, "0:4:2", FALSE);
-  set_path_visibility (fixture, "0:4:4", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
-  set_path_visibility (fixture, "0:4", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, "0:3", 0);
-
-  set_path_visibility (fixture, "0:2", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0:4", 0);
-
-  /* Once 0:4:0 got inserted, 0:4 became a parent.  Because 0:4 is
-   * not visible, not signals are emitted.
-   */
-  set_path_visibility (fixture, "0:4:2", TRUE);
-  set_path_visibility (fixture, "0:4:4", TRUE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, "0:4", 2);
-}
-
-static void
-filled_hide_child_levels_root_expanded (FilterTest    *fixture,
-                                        gconstpointer  user_data)
-{
-  GtkTreePath *path;
-
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
-  gtk_tree_path_free (path);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
-  set_path_visibility (fixture, "0:2", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
-  set_path_visibility (fixture, "0:4", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "0:4:3", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "0:4:0", FALSE);
-  set_path_visibility (fixture, "0:4:1", FALSE);
-  set_path_visibility (fixture, "0:4:2", FALSE);
-  set_path_visibility (fixture, "0:4:4", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
-  set_path_visibility (fixture, "0:4", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, "0:3", 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
-  set_path_visibility (fixture, "0:2", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0:4", 0);
-
-  /* has-child-toggled for 0:4 is required.  */
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
-  set_path_visibility (fixture, "0:4:2", TRUE);
-  set_path_visibility (fixture, "0:4:4", TRUE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, "0:4", 2);
-}
-
-
-static void
-filled_vroot_hide_root_level (FilterTest    *fixture,
-                              gconstpointer  user_data)
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  /* These changes do not affect the filter's root level */
-  set_path_visibility (fixture, "0", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
-
-  set_path_visibility (fixture, "4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
-
-  /* Even though we set the virtual root parent node to FALSE,
-   * the virtual root contents remain.
-   */
-  set_path_visibility (fixture, "2", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
-
-  /* No change */
-  set_path_visibility (fixture, "1", FALSE);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
-
-  set_path_visibility (fixture, "3", FALSE);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
-
-  check_filter_model_with_root (fixture, path);
-
-  /* Show some */
-  set_path_visibility (fixture, "2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
-
-  set_path_visibility (fixture, "1", TRUE);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
-
-  set_path_visibility (fixture, "3", TRUE);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
-
-  check_filter_model_with_root (fixture, path);
-
-  /* Now test changes in the virtual root level */
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
-  set_path_visibility (fixture, "2:2", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
-  set_path_visibility (fixture, "2:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "1:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
-  set_path_visibility (fixture, "2:4", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
-
-  set_path_visibility (fixture, "2", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  set_path_visibility (fixture, "2:0", FALSE);
-  set_path_visibility (fixture, "2:1", FALSE);
-  set_path_visibility (fixture, "2:2", FALSE);
-  set_path_visibility (fixture, "2:3", FALSE);
-  set_path_visibility (fixture, "2:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  set_path_visibility (fixture, "2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  set_path_visibility (fixture, "1:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2:4", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  set_path_visibility (fixture, "2:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  set_path_visibility (fixture, "2", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  set_path_visibility (fixture, "2:0", TRUE);
-  set_path_visibility (fixture, "2:1", TRUE);
-  set_path_visibility (fixture, "2:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
-}
-
-static void
-filled_vroot_hide_child_levels (FilterTest    *fixture,
-                                gconstpointer  user_data)
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  set_path_visibility (fixture, "2:0:2", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
-
-  set_path_visibility (fixture, "2:0:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "2:0:4:3", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "2:0:4:0", FALSE);
-  set_path_visibility (fixture, "2:0:4:1", FALSE);
-  set_path_visibility (fixture, "2:0:4:2", FALSE);
-  set_path_visibility (fixture, "2:0:4:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
-  set_path_visibility (fixture, "2:0:4", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, "0:3", 0);
-
-  set_path_visibility (fixture, "2:0:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0:4", 0);
-
-  /* Once 0:4:0 got inserted, 0:4 became a parent. However, 0:4 is not
-   * visible, so no signal should be emitted.
-   */
-  set_path_visibility (fixture, "2:0:4:2", TRUE);
-  set_path_visibility (fixture, "2:0:4:4", TRUE);
-  check_level_length (fixture->filter, "0:4", 2);
-  signal_monitor_assert_is_empty (fixture->monitor);
-}
-
-static void
-filled_vroot_hide_child_levels_root_expanded (FilterTest    *fixture,
-                                              gconstpointer  user_data)
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-  GtkTreePath *tmp_path;
-
-  tmp_path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), tmp_path, FALSE);
-  gtk_tree_path_free (tmp_path);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
-  set_path_visibility (fixture, "2:0:2", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
-  set_path_visibility (fixture, "2:0:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "2:0:4:3", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  set_path_visibility (fixture, "2:0:4:0", FALSE);
-  set_path_visibility (fixture, "2:0:4:1", FALSE);
-  set_path_visibility (fixture, "2:0:4:2", FALSE);
-  set_path_visibility (fixture, "2:0:4:4", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
-
-  /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
-  set_path_visibility (fixture, "2:0:4", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, "0:3", 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
-  set_path_visibility (fixture, "2:0:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "0:4", 0);
-
-  /* Once 0:4:0 got inserted, 0:4 became a parent */
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
-  set_path_visibility (fixture, "2:0:4:2", TRUE);
-  set_path_visibility (fixture, "2:0:4:4", TRUE);
-  check_level_length (fixture->filter, "0:4", 2);
-  signal_monitor_assert_is_empty (fixture->monitor);
-}
-
-static void
-empty_show_nodes (FilterTest    *fixture,
-                  gconstpointer  user_data)
-{
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "3", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 0);
-
-  set_path_visibility (fixture, "3:2:2", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "3:2", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 1);
-  check_level_length (fixture->filter, "0:0:0", 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  set_path_visibility (fixture, "3", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "3:2:1", TRUE);
-  set_path_visibility (fixture, "3", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 2);
-  check_level_length (fixture->filter, "0:0:0", 0);
-}
-
-static void
-empty_show_multiple_nodes (FilterTest    *fixture,
-                           gconstpointer  user_data)
-{
-  GtkTreeIter iter;
-  GtkTreePath *changed_path;
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
-
-  /* We simulate a change in visible func condition with this.  The
-   * visibility state of multiple nodes changes at once, we emit row-changed
-   * for these nodes (and others) after that.
-   */
-  filter_test_block_signals (fixture);
-  set_path_visibility (fixture, "3", TRUE);
-  set_path_visibility (fixture, "4", TRUE);
-  filter_test_unblock_signals (fixture);
-
-  changed_path = gtk_tree_path_new ();
-  gtk_tree_path_append_index (changed_path, 2);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
-                           &iter, changed_path);
-  /* Invisible node - so no signals expected */
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_next (changed_path);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_next (changed_path);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_free (changed_path);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 2);
-  check_level_length (fixture->filter, "0", 0);
-
-  set_path_visibility (fixture, "3:2:2", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 2);
-  check_level_length (fixture->filter, "0", 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "3:2", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 2);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 1);
-  check_level_length (fixture->filter, "0:0:0", 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  set_path_visibility (fixture, "3", FALSE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "3:2:1", TRUE);
-  set_path_visibility (fixture, "3", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 2);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 2);
-  check_level_length (fixture->filter, "0:0:0", 0);
-}
-
-static void
-empty_vroot_show_nodes (FilterTest    *fixture,
-                        gconstpointer  user_data)
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  set_path_visibility (fixture, "2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  set_path_visibility (fixture, "2:2:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 0);
-
-  set_path_visibility (fixture, "3", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  set_path_visibility (fixture, "2:2", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2:2:1", TRUE);
-  set_path_visibility (fixture, "2:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 2);
-  check_level_length (fixture->filter, "0:1", 0);
-}
-
-static void
-empty_vroot_show_multiple_nodes (FilterTest    *fixture,
-                                 gconstpointer  user_data)
-{
-  GtkTreeIter iter;
-  GtkTreePath *changed_path;
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* We simulate a change in visible func condition with this.  The
-   * visibility state of multiple nodes changes at once, we emit row-changed
-   * for these nodes (and others) after that.
-   */
-  filter_test_block_signals (fixture);
-  set_path_visibility (fixture, "2", TRUE);
-  set_path_visibility (fixture, "3", TRUE);
-  filter_test_unblock_signals (fixture);
-
-  changed_path = gtk_tree_path_new ();
-  gtk_tree_path_append_index (changed_path, 1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
-                           &iter, changed_path);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_next (changed_path);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_next (changed_path);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_next (changed_path);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_free (changed_path);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  set_path_visibility (fixture, "2:2:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
-
-  /* Again, we simulate a call to refilter */
-  filter_test_block_signals (fixture);
-  set_path_visibility (fixture, "2:2", TRUE);
-  set_path_visibility (fixture, "2:3", TRUE);
-  filter_test_unblock_signals (fixture);
-
-  changed_path = gtk_tree_path_new ();
-  gtk_tree_path_append_index (changed_path, 2);
-  gtk_tree_path_append_index (changed_path, 1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
-                           &iter, changed_path);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_next (changed_path);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_next (changed_path);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_next (changed_path);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
-                              changed_path, &iter);
-
-  gtk_tree_path_free (changed_path);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 2);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 0);
-
-  set_path_visibility (fixture, "3", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 2);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
-  set_path_visibility (fixture, "2:2", FALSE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2:2:1", TRUE);
-  set_path_visibility (fixture, "2:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 2);
-  check_level_length (fixture->filter, "0", 2);
-  check_level_length (fixture->filter, "0:1", 0);
-}
-
-
-static void
-unfiltered_hide_single (FilterTest    *fixture,
-                        gconstpointer  user_data)
-
-{
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  set_path_visibility (fixture, "2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-
-  /* The view only shows the root level, so we only expect signals
-   * for the root level.
-   */
-  filter_test_append_refilter_signals (fixture, 1);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_hide_single_root_expanded (FilterTest    *fixture,
-                                      gconstpointer  user_data)
-
-{
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  set_path_visibility (fixture, "2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals (fixture, 2);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_hide_single_child (FilterTest    *fixture,
-                              gconstpointer  user_data)
-
-{
-  /* This row is not shown, so its signal is not propagated */
-  set_path_visibility (fixture, "2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-
-  /* The view only shows the root level, so we only expect signals
-   * for the root level.
-   */
-  filter_test_append_refilter_signals (fixture, 0);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_hide_single_child_root_expanded (FilterTest    *fixture,
-                                            gconstpointer  user_data)
-
-{
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals (fixture, 2);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_hide_single_multi_level (FilterTest    *fixture,
-                                    gconstpointer  user_data)
-
-{
-  /* This row is not shown, so its signal is not propagated */
-  set_path_visibility (fixture, "2:2:2", FALSE);
-
-  /* This row is not shown, so its signal is not propagated */
-  set_path_visibility (fixture, "2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
-
-  /* The view only shows the root level, so we only expect signals
-   * for the root level.
-   */
-  filter_test_append_refilter_signals (fixture, 1);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
-
-  set_path_visibility (fixture, "2:2", TRUE);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_hide_single_multi_level_root_expanded (FilterTest    *fixture,
-                                                  gconstpointer  user_data)
-
-{
-  /* This row is not shown, so its signal is not propagated */
-  set_path_visibility (fixture, "2:2:2", FALSE);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals (fixture, 2);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2", TRUE);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
-}
-
-
-
-static void
-unfiltered_vroot_hide_single (FilterTest    *fixture,
-                              gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  set_path_visibility (fixture, "2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-
-  /* The view only shows the root level, so we only expect signals
-   * for the root level.  (Though for the depth argument, we have to
-   * take the virtual root into account).
-   */
-  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_vroot_hide_single_child (FilterTest    *fixture,
-                                    gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  /* Not visible, so no signal will be received. */
-  set_path_visibility (fixture, "2:2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-
-  /* The view only shows the root level, so we only expect signals
-   * for the root level.  (Though for the depth argument, we have to
-   * take the virtual root into account).
-   */
-  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_vroot_hide_single_child_root_expanded (FilterTest    *fixture,
-                                                  gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_vroot_hide_single_multi_level (FilterTest    *fixture,
-                                          gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  /* This row is not shown, so its signal is not propagated */
-  set_path_visibility (fixture, "2:2:2:2", FALSE);
-
-  /* Not shown, so no signal */
-  set_path_visibility (fixture, "2:2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
-
-  /* We only expect signals for the root level.  The depth is 2
-   * because we have to take the virtual root into account.
-   */
-  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
-
-  /* Not shown, so no signal */
-  set_path_visibility (fixture, "2:2:2", TRUE);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_vroot_hide_single_multi_level_root_expanded (FilterTest    *fixture,
-                                                        gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  /* This row is not shown, so its signal is not propagated */
-  set_path_visibility (fixture, "2:2:2:2", FALSE);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2:2", FALSE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2:2", TRUE);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
-}
-
-static void
-unfiltered_show_single (FilterTest    *fixture,
-                        gconstpointer  user_data)
-
-{
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  set_path_visibility (fixture, "2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-
-  /* We only expect signals for the root level */
-  filter_test_append_refilter_signals (fixture, 1);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 1);
-}
-
-static void
-unfiltered_show_single_child (FilterTest    *fixture,
-                              gconstpointer  user_data)
-
-{
-  set_path_visibility (fixture, "2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-
-  /* We only expect signals for the root level */
-  filter_test_append_refilter_signals (fixture, 1);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* From here we are filtered, "2" in the real model is "0" in the filter
-   * model.
-   */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2", TRUE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-}
-
-static void
-unfiltered_show_single_child_root_expanded (FilterTest    *fixture,
-                                            gconstpointer  user_data)
-
-{
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals (fixture, 2);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* From here we are filtered, "2" in the real model is "0" in the filter
-   * model.
-   */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2", TRUE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-}
-
-static void
-unfiltered_show_single_multi_level (FilterTest    *fixture,
-                                    gconstpointer  user_data)
-
-{
-  /* The view is not showing these rows (collapsed state), so it is not
-   * referenced.  The signal should not go through.
-   */
-  set_path_visibility (fixture, "2:2:2", TRUE);
-  set_path_visibility (fixture, "2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
-
-  /* We only expect signals for the first level */
-  filter_test_append_refilter_signals (fixture, 1);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* From here we are filtered, "2" in the real model is "0" in the filter
-   * model.
-   */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 1);
-}
-
-static void
-unfiltered_show_single_multi_level_root_expanded (FilterTest    *fixture,
-                                                  gconstpointer  user_data)
-
-{
-  /* The view is not showing this row (collapsed state), so it is not
-   * referenced.  The signal should not go through.
-   */
-  set_path_visibility (fixture, "2:2:2", TRUE);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals (fixture, 2);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* From here we are filtered, "2" in the real model is "0" in the filter
-   * model.
-   */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2", TRUE);
-  check_filter_model (fixture);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 1);
-}
-
-static void
-unfiltered_vroot_show_single (FilterTest    *fixture,
-                              gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  set_path_visibility (fixture, "2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-
-  /* The view only shows the root level, so the filter model only has
-   * the first two levels cached.
-   */
-  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 1);
-}
-
-static void
-unfiltered_vroot_show_single_child (FilterTest    *fixture,
-                                    gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  set_path_visibility (fixture, "2:2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-
-  /* The view only shows the root level, so the filter model only has
-   * the first two levels cached.
-   */
-  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* From here we are filtered, "2" in the real model is "0" in the filter
-   * model.
-   */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2:2", TRUE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-}
-
-static void
-unfiltered_vroot_show_single_child_root_expanded (FilterTest    *fixture,
-                                                  gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* From here we are filtered, "2" in the real model is "0" in the filter
-   * model.
-   */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2:2", TRUE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-}
-
-
-static void
-unfiltered_vroot_show_single_multi_level (FilterTest    *fixture,
-                                          gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  /* The view is not showing this row (collapsed state), so it is not
-   * referenced.  The signal should not go through.
-   */
-  set_path_visibility (fixture, "2:2:2:2", TRUE);
-
-  set_path_visibility (fixture, "2:2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
-
-  /* We only expect signals for the root level */
-  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* From here we are filtered, "2" in the real model is "0" in the filter
-   * model.
-   */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 1);
-}
-
-static void
-unfiltered_vroot_show_single_multi_level_root_expanded (FilterTest    *fixture,
-                                                        gconstpointer  user_data)
-
-{
-  GtkTreePath *path = (GtkTreePath *)user_data;
-
-  /* The view is not showing this row (collapsed state), so it is not
-   * referenced.  The signal should not go through.
-   */
-  set_path_visibility (fixture, "2:2:2:2", TRUE);
-
-  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
-  set_path_visibility (fixture, "2:2:2", TRUE);
-
-  signal_monitor_assert_is_empty (fixture->monitor);
-  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
-  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
-
-  filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
-  filter_test_enable_filter (fixture);
-
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 0);
-
-  /* From here we are filtered, "2" in the real model is "0" in the filter
-   * model.
-   */
-  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "2:2", TRUE);
-  check_filter_model_with_root (fixture, path);
-  check_level_length (fixture->filter, NULL, 1);
-  check_level_length (fixture->filter, "0", 1);
-  check_level_length (fixture->filter, "0:0", 1);
-}
-
-static void
-unfiltered_rows_reordered_root_level (FilterTest    *fixture,
-                                      gconstpointer  user_data)
-{
-  int order0[] = { 1, 2, 3, 4, 0 };
-  int order1[] = { 0, 2, 1, 3, 4 };
-  int order2[] = { 4, 0, 1, 2, 3 };
-  GtkTreeIter iter0, iter1, iter2, iter3, iter4;
-  GtkTreePath *path;
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter0, "0");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter1, "1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter2, "2");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter3, "3");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter4, "4");
-
-  path = gtk_tree_path_new ();
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order0, 5);
-  gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order1, 5);
-  gtk_tree_store_move_after (fixture->store, &iter2, &iter3);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order2, 5);
-  gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_path_free (path);
-}
-
-static void
-unfiltered_rows_reordered_child_level (FilterTest    *fixture,
-                                       gconstpointer  user_data)
-{
-  int order0[] = { 1, 2, 3, 4, 0 };
-  int order1[] = { 0, 2, 1, 3, 4 };
-  int order2[] = { 4, 0, 1, 2, 3 };
-  GtkTreeIter iter0, iter1, iter2, iter3, iter4;
-  GtkTreePath *path;
-
-  /* Expand row 0 */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter0, "0:0");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter1, "0:1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter2, "0:2");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter3, "0:3");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter4, "0:4");
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order0, 5);
-  gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order1, 5);
-  gtk_tree_store_move_after (fixture->store, &iter2, &iter3);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order2, 5);
-  gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_path_free (path);
-}
-
-static void
-filtered_rows_reordered_root_level_first_hidden (FilterTest    *fixture,
-                                                 gconstpointer  user_data)
-{
-  int order0[] = { 1, 2, 3, 0 };
-  int order1[] = { 0, 2, 1, 3 };
-  int order2[] = { 3, 0, 1, 2 };
-  GtkTreeIter iter1, iter2, iter3, iter4;
-  GtkTreePath *path;
-
-  /* Hide middle path */
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0");
-  set_path_visibility (fixture, "0", FALSE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter1, "1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter2, "2");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter3, "3");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter4, "4");
-
-  path = gtk_tree_path_new ();
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order0, 4);
-  gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order1, 4);
-  gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order2, 4);
-  gtk_tree_store_move_before (fixture->store, &iter1, &iter2);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_path_free (path);
-}
-
-static void
-filtered_rows_reordered_root_level_middle_hidden (FilterTest    *fixture,
-                                                  gconstpointer  user_data)
-{
-  int order0[] = { 1, 2, 3, 0 };
-  int order1[] = { 0, 2, 1, 3 };
-  int order2[] = { 3, 0, 1, 2 };
-  GtkTreeIter iter0, iter1, iter3, iter4;
-  GtkTreePath *path;
-
-  /* Hide middle path */
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "2");
-  set_path_visibility (fixture, "2", FALSE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter0, "0");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter1, "1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter3, "3");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter4, "4");
-
-  path = gtk_tree_path_new ();
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order0, 4);
-  gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order1, 4);
-  gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order2, 4);
-  gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_path_free (path);
-}
-
-static void
-filtered_rows_reordered_child_level_first_hidden (FilterTest    *fixture,
-                                                  gconstpointer  user_data)
-{
-  int order0[] = { 1, 2, 3, 0 };
-  int order1[] = { 0, 2, 1, 3 };
-  int order2[] = { 3, 0, 1, 2 };
-  GtkTreeIter iter1, iter2, iter3, iter4;
-  GtkTreePath *path;
-
-  /* Expand row 0 */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, TRUE);
-
-  /* Hide middle path */
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:0");
-  set_path_visibility (fixture, "0:0", FALSE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter1, "0:1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter2, "0:2");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter3, "0:3");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter4, "0:4");
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order0, 4);
-  gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order1, 4);
-  gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order2, 4);
-  gtk_tree_store_move_before (fixture->store, &iter1, &iter2);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_path_free (path);
-}
-
-static void
-filtered_rows_reordered_child_level_middle_hidden (FilterTest    *fixture,
-                                                   gconstpointer  user_data)
-{
-  int order0[] = { 1, 2, 3, 0 };
-  int order1[] = { 0, 2, 1, 3 };
-  int order2[] = { 3, 0, 1, 2 };
-  GtkTreeIter iter0, iter1, iter3, iter4;
-  GtkTreePath *path;
-
-  /* Expand row 0 */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
-
-  /* Hide middle path */
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:2");
-  set_path_visibility (fixture, "0:2", FALSE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter0, "0:0");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter1, "0:1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter3, "0:3");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter4, "0:4");
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order0, 4);
-  gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order1, 4);
-  gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order2, 4);
-  gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_path_free (path);
-}
-
-static void
-filtered_rows_reordered_child_level_4_hidden (FilterTest    *fixture,
-                                              gconstpointer  user_data)
-{
-  int order0[] = { 0 };
-  GtkTreeIter iter1, iter4;
-  GtkTreePath *path;
-
-  /* Expand row 0 */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
-
-  /* Hide last 4 paths */
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:4");
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:3");
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:2");
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:0");
-  set_path_visibility (fixture, "0:4", FALSE);
-  set_path_visibility (fixture, "0:3", FALSE);
-  set_path_visibility (fixture, "0:2", FALSE);
-  set_path_visibility (fixture, "0:0", FALSE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter1, "0:1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter4, "0:4");
-
-  signal_monitor_append_signal_reordered (fixture->monitor,
-                                          ROWS_REORDERED,
-                                          path, order0, 1);
-  gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_path_free (path);
-}
-
-static void
-filtered_rows_reordered_child_level_all_hidden (FilterTest    *fixture,
-                                                gconstpointer  user_data)
-{
-  GtkTreeIter iter1, iter4;
-  GtkTreePath *path;
-
-  /* Expand row 0 */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
-  gtk_tree_path_free (path);
-
-  /* Hide last 4 paths */
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:4");
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:3");
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:2");
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:1");
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_DELETED, "0:0");
-  signal_monitor_append_signal (fixture->monitor,
-                                ROW_HAS_CHILD_TOGGLED, "0");
-  set_path_visibility (fixture, "0:4", FALSE);
-  set_path_visibility (fixture, "0:3", FALSE);
-  set_path_visibility (fixture, "0:2", FALSE);
-  set_path_visibility (fixture, "0:1", FALSE);
-  set_path_visibility (fixture, "0:0", FALSE);
-  signal_monitor_assert_is_empty (fixture->monitor);
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter1, "0:1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
-                                       &iter4, "0:4");
-
-  gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
-  signal_monitor_assert_is_empty (fixture->monitor);
-}
-
-static void
-insert_before (void)
-{
-  GtkTreeStore *store;
-  GtkTreeModel *filter;
-  GtkWidget *tree_view;
-  SignalMonitor *monitor;
-  GtkTreeIter iter;
-  GtkTreeIter last_iter;
-  GtkTreePath *path;
-
-  /* This tests two aspects of the row-inserted handling:
-   *   1) If the newly inserted node was already handled by building
-   *      the root level, don't handle it a second time.
-   *   2) Offsets of existing nodes must be updated when a new
-   *      node is inserted.
-   */
-
-  store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
-                                            1);
-
-  tree_view = gtk_tree_view_new_with_model (filter);
-  monitor = signal_monitor_new (filter);
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 0);
-
-  /* Insert 0 */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
-                                     0, "Foo", 1, TRUE, -1);
-
-  signal_monitor_assert_is_empty (monitor);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
-
-  /* Insert 1 */
-  path = gtk_tree_path_new_from_indices (1, -1);
-  signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
-                                     0, "Foo", 1, TRUE, -1);
-  last_iter = iter;
-
-  signal_monitor_assert_is_empty (monitor);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
-
-  /* Insert on 1 again -- invisible */
-  gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
-                                     0, "Foo", 1, FALSE, -1);
-
-  signal_monitor_assert_is_empty (monitor);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
-
-  /* Insert on 1 again -- visible */
-  path = gtk_tree_path_new_from_indices (1, -1);
-  signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
-                                     0, "Foo", 1, TRUE, -1);
-
-  signal_monitor_assert_is_empty (monitor);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 3);
-
-  /* Modify the iter that should be at the last position and check the
-   * signal we get.
-   */
-  path = gtk_tree_path_new_from_indices (2, -1);
-  signal_monitor_append_signal_path (monitor, ROW_CHANGED, path);
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_set (store, &last_iter, 0, "Foo changed", -1);
-
-  signal_monitor_assert_is_empty (monitor);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 3);
-
-  g_object_unref (filter);
-  g_object_unref (store);
-  gtk_widget_destroy (tree_view);
-}
-
-static void
-insert_child (void)
-{
-  GtkTreeStore *store;
-  GtkTreeModel *filter;
-  GtkWidget *tree_view;
-  SignalMonitor *monitor;
-  GtkTreeIter parent, iter;
-  GtkTreePath *path;
-
-  store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-
-  gtk_tree_store_insert_with_values (store, &parent, NULL, 0,
-                                     0, "Parent", 1, TRUE, -1);
-
-
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
-                                            1);
-
-  tree_view = gtk_tree_view_new_with_model (filter);
-  monitor = signal_monitor_new (filter);
-
-  /* Insert child -- invisible */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
-  /* The signal is received twice, once a pass through from GtkTreeStore
-   * and one generated by GtkTreeModelFilter.  Not accurate, but cannot
-   * hurt.
-   */
-  signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_insert_with_values (store, &iter, &parent, 1,
-                                     0, "Child", 1, FALSE, -1);
-
-  signal_monitor_assert_is_empty (monitor);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
-
-  /* Insert child */
-  path = gtk_tree_path_new_from_indices (0, 0, -1);
-  gtk_tree_path_up (path); /* 0 */
-  signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
-                                     0, "Child", 1, TRUE, -1);
-
-  signal_monitor_assert_is_empty (monitor);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
-
-  /* Insert child -- invisible */
-  gtk_tree_store_insert_with_values (store, &iter, &parent, 1,
-                                     0, "Child", 1, FALSE, -1);
-
-  signal_monitor_assert_is_empty (monitor);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
-
-  g_object_unref (filter);
-  g_object_unref (store);
-  gtk_widget_destroy (tree_view);
-}
-
-
-
-static void
-remove_node (void)
-{
-  GtkTreeIter iter, iter1, iter2, iter3;
-  GtkListStore *list;
-  GtkTreeModel *filter;
-  GtkWidget *view G_GNUC_UNUSED;
-
-  list = gtk_list_store_new (1, G_TYPE_INT);
-  gtk_list_store_insert_with_values (list, &iter1, 0, 0, 1, -1);
-  gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
-  gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
-  gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
-  gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
-  gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
-  gtk_list_store_insert_with_values (list, &iter2, 6, 0, 7, -1);
-  gtk_list_store_insert_with_values (list, &iter3, 7, 0, 8, -1);
-
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
-  view = gtk_tree_view_new_with_model (filter);
-
-  gtk_list_store_remove (list, &iter1);
-  gtk_list_store_remove (list, &iter3);
-  gtk_list_store_remove (list, &iter2);
-
-  gtk_widget_destroy (view);
-  g_object_unref (filter);
-  g_object_unref (list);
-}
-
-static void
-remove_node_vroot (void)
-{
-  GtkTreeIter parent, root;
-  GtkTreeIter iter, iter1, iter2, iter3;
-  GtkTreeStore *tree;
-  GtkTreeModel *filter;
-  GtkTreePath *path;
-  GtkWidget *view G_GNUC_UNUSED;
-
-  tree = gtk_tree_store_new (1, G_TYPE_INT);
-  gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
-  gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
-
-  gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
-  gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
-  gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
-
-  path = gtk_tree_path_new_from_indices (0, 0, -1);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
-  gtk_tree_path_free (path);
-
-  view = gtk_tree_view_new_with_model (filter);
-
-  gtk_tree_store_remove (tree, &iter1);
-  gtk_tree_store_remove (tree, &iter3);
-  gtk_tree_store_remove (tree, &iter2);
-
-  gtk_widget_destroy (view);
-  g_object_unref (filter);
-  g_object_unref (tree);
-}
-
-static void
-remove_vroot_ancestor (void)
-{
-  GtkTreeIter parent, root;
-  GtkTreeIter iter, iter1, iter2, iter3;
-  GtkTreeStore *tree;
-  GtkTreeModel *filter;
-  GtkTreePath *path;
-  GtkWidget *view G_GNUC_UNUSED;
-
-  tree = gtk_tree_store_new (1, G_TYPE_INT);
-  gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
-  gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
-
-  gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
-  gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
-  gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
-
-  path = gtk_tree_path_new_from_indices (0, 0, -1);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
-  gtk_tree_path_free (path);
-
-  view = gtk_tree_view_new_with_model (filter);
-
-  gtk_tree_store_remove (tree, &parent);
-
-  gtk_widget_destroy (view);
-  g_object_unref (filter);
-  g_object_unref (tree);
-}
-
-static void
-ref_count_single_level (void)
-{
-  GtkTreeIter iter[5];
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[0], NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[1], NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[2], NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[3], NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[4], NULL);
-
-  assert_root_level_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &iter[0], 2);
-  assert_node_ref_count (ref_model, &iter[1], 1);
-  assert_node_ref_count (ref_model, &iter[2], 1);
-  assert_node_ref_count (ref_model, &iter[3], 1);
-  assert_node_ref_count (ref_model, &iter[4], 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_node_ref_count (ref_model, &iter[0], 1);
-  assert_node_ref_count (ref_model, &iter[1], 0);
-  assert_node_ref_count (ref_model, &iter[2], 0);
-  assert_node_ref_count (ref_model, &iter[3], 0);
-  assert_node_ref_count (ref_model, &iter[4], 0);
-
-  g_object_unref (filter_model);
-
-  assert_node_ref_count (ref_model, &iter[0], 0);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_two_levels (void)
-{
-  GtkTreeIter parent1, parent2, iter, iter_first;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_first, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  /* This is quite confusing:
-   *  - node 0 has a ref count of 2 because it is referenced as the
-   *    first node in a level and by the tree view.
-   *  - node 1 has a ref count of 2 because it is referenced by its
-   *    child level and by the tree view.
-   */
-  assert_root_level_referenced (ref_model, 2);
-  assert_node_ref_count (ref_model, &iter_first, 1);
-  assert_node_ref_count (ref_model, &iter, 0);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_first, 2);
-  assert_node_ref_count (ref_model, &iter, 1);
-
-  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
-
-  /* The child level is not destroyed because its parent is visible */
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_first, 1);
-  assert_node_ref_count (ref_model, &iter, 0);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_first, 1);
-  assert_node_ref_count (ref_model, &iter, 0);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_node_ref_count (ref_model, &iter_first, 1);
-  assert_node_ref_count (ref_model, &iter, 0);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  /* The root level and first level remain cached, only the references on the
-   * first nodes of these levels are kept.
-   */
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_first, 1);
-  assert_node_ref_count (ref_model, &iter, 0);
-
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_three_levels (void)
-{
-  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
-  GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   *   + parent1
-   *     + iter_parent1
-   *   + parent2
-   *     + iter_parent2_first
-   *     + iter_parent2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  /* This is quite confusing:
-   *  - node 0 has a ref count of 2 because it is referenced as the
-   *    first node in a level and by the tree view.
-   *  - node 1 has a ref count of 2 because it is referenced by its
-   *    child level and by the tree view.
-   */
-  assert_root_level_referenced (ref_model, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_unreferenced (ref_model, &parent2);
-
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 2);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_path_append_index (path, 1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_path_up (path);
-  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_widget_destroy (tree_view);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  /* The root level and first level remain cached, only the references on the
-   * first nodes of these levels are kept.  Grandparent2 is the parent
-   * of the first level with parent1, so grandparent2 keeps a reference
-   * as well.
-   */
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_delete_row (void)
-{
-  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
-  GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   *   + parent1
-   *     + iter_parent1
-   *   + parent2
-   *     + iter_parent2_first
-   *     + iter_parent2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_root_level_referenced (ref_model, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_unreferenced (ref_model, &parent2);
-
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 2);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter_parent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 2);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent2, 3);
-  assert_level_referenced (ref_model, 2, &parent2);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-
-  gtk_widget_destroy (tree_view);
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-
-  g_object_unref (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_filter_row_length_1 (void)
-{
-  GtkTreeIter level1_1;
-  GtkTreeIter level2_1;
-  GtkTreeIter level3_1;
-  GtkTreeIter level4_1;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-
-  /* + level1_1
-   *   + level2_1
-   *     + level3_1
-   *       + level4_1
-   *
-   * Node level1_1 is expanded.  This makes that levels 1 and 2 are
-   * visible.  Level 3 is cached because its parent is visible.  Level 4
-   * is not cached.
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 3);
-  assert_node_ref_count (ref_model, &level3_1, 1);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 3);
-  assert_node_ref_count (ref_model, &level3_1, 1);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  /* level3_1 has a visible parent, so the node is kept in the cache. */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 3);
-  assert_node_ref_count (ref_model, &level3_1, 1);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  /* level2_1 has a visible parent, so is kept in the cache.  However,
-   * the external reference should be released.
-   */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  gtk_widget_destroy (tree_view);
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-
-  g_object_unref (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 0);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_filter_row_length_1_remove_in_root_level (void)
-{
-  GtkTreeIter level1_1;
-  GtkTreeIter level2_1;
-  GtkTreeIter level3_1;
-  GtkTreeIter level4_1;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-
-  /* + level1_1
-   *   + level2_1
-   *     + level3_1
-   *       + level4_1
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 3);
-  assert_node_ref_count (ref_model, &level3_1, 3);
-  assert_node_ref_count (ref_model, &level4_1, 2);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  gtk_widget_destroy (tree_view);
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  g_object_unref (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 0);
-  assert_node_ref_count (ref_model, &level2_1, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_filter_row_length_1_remove_in_child_level (void)
-{
-  GtkTreeIter level1_1;
-  GtkTreeIter level2_1;
-  GtkTreeIter level3_1;
-  GtkTreeIter level4_1;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-
-  /* + level1_1
-   *   + level2_1
-   *     + level3_1
-   *       + level4_1
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 3);
-  assert_node_ref_count (ref_model, &level3_1, 3);
-  assert_node_ref_count (ref_model, &level4_1, 2);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 3);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  gtk_widget_destroy (tree_view);
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  g_object_unref (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 0);
-  assert_node_ref_count (ref_model, &level2_1, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_filter_row_length_gt_1 (void)
-{
-  GtkTreeIter level1_1, level1_2;
-  GtkTreeIter level2_1, level2_2;
-  GtkTreeIter level3_1, level3_2;
-  GtkTreeIter level4_1, level4_2;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-
-  /* + level1_1
-   * + level1_2
-   *   + level2_1
-   *   + level2_2
-   *     + level3_1
-   *     + level3_2
-   *       + level4_1
-   *       + level4_2
-   *
-   * Node level1_2 is expanded.  This makes that levels 1 and 2 are
-   * visible.  Level 3 is cached because its parent is visible.  Level 4
-   * is not cached.
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_2, &level1_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_2, &level2_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_2, &level3_2);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_2, 0, TRUE, -1);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 2);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level2_2, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 2);
-  assert_node_ref_count (ref_model, &level2_1, 2);
-  assert_node_ref_count (ref_model, &level2_2, 2);
-  assert_node_ref_count (ref_model, &level3_1, 1);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 2);
-  assert_node_ref_count (ref_model, &level2_1, 2);
-  assert_node_ref_count (ref_model, &level2_2, 2);
-  assert_node_ref_count (ref_model, &level3_1, 1);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 2);
-  assert_node_ref_count (ref_model, &level2_1, 2);
-  assert_node_ref_count (ref_model, &level2_2, 2);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level3_2, 1);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 2);
-  assert_node_ref_count (ref_model, &level2_1, 2);
-  assert_node_ref_count (ref_model, &level2_2, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 0);
-  assert_node_ref_count (ref_model, &level2_1, 0);
-  assert_node_ref_count (ref_model, &level2_2, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  gtk_widget_destroy (tree_view);
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &level1_1, 1);
-
-  g_object_unref (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 0);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_filter_row_length_gt_1_visible_children (void)
-{
-  GtkTreeIter level1_1, level1_2;
-  GtkTreeIter level2_1, level2_2;
-  GtkTreeIter level3_1, level3_2;
-  GtkTreeIter level4_1, level4_2;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-
-  /* + level1_1
-   * + level1_2
-   *   + level2_1
-   *   + level2_2
-   *     + level3_1
-   *     + level3_2
-   *       + level4_1
-   *       + level4_2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_2, &level1_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_2, &level2_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_2, &level3_2);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_2, 0, TRUE, -1);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 2);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level2_2, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 2);
-  assert_node_ref_count (ref_model, &level2_1, 2);
-  assert_node_ref_count (ref_model, &level2_2, 2);
-  assert_node_ref_count (ref_model, &level3_1, 2);
-  assert_node_ref_count (ref_model, &level3_2, 2);
-  assert_node_ref_count (ref_model, &level4_1, 2);
-  assert_node_ref_count (ref_model, &level4_2, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &level1_1, 2);
-  assert_node_ref_count (ref_model, &level1_2, 2);
-  assert_node_ref_count (ref_model, &level2_1, 2);
-  assert_node_ref_count (ref_model, &level2_2, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  gtk_widget_destroy (tree_view);
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  assert_node_ref_count (ref_model, &level1_1, 1);
-  assert_node_ref_count (ref_model, &level1_2, 1);
-  assert_node_ref_count (ref_model, &level2_1, 1);
-  assert_node_ref_count (ref_model, &level2_2, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  g_object_unref (filter_model);
-
-  assert_node_ref_count (ref_model, &level1_1, 0);
-  assert_node_ref_count (ref_model, &level1_2, 0);
-  assert_node_ref_count (ref_model, &level2_1, 0);
-  assert_node_ref_count (ref_model, &level2_2, 0);
-  assert_node_ref_count (ref_model, &level3_1, 0);
-  assert_node_ref_count (ref_model, &level3_2, 0);
-  assert_node_ref_count (ref_model, &level4_1, 0);
-  assert_node_ref_count (ref_model, &level4_2, 0);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_cleanup (void)
-{
-  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
-  GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   *   + parent1
-   *     + iter_parent1
-   *   + parent2
-   *     + iter_parent2_first
-   *     + iter_parent2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 2);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  /* The root level and first level remain cached, only the references on the
-   * first nodes of these levels are kept.  Grandparent2 is the parent
-   * of the first level with parent1, so grandparent2 keeps a reference
-   * as well.
-   */
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_row_ref (void)
-{
-  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
-  GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-  GtkTreePath *path;
-  GtkTreeRowReference *row_ref;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   *   + parent1
-   *     + iter_parent1
-   *   + parent2
-   *     + iter_parent2
-   *     + iter_parent2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
-  row_ref = gtk_tree_row_reference_new (filter_model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 3);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
-  row_ref = gtk_tree_row_reference_new (filter_model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 3);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-
-  gtk_widget_destroy (tree_view);
-
-  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
-
-  /* The root level and first level remain cached, only the references on the
-   * first nodes of these levels are kept.  Grandparent2 is the parent
-   * of the first level with parent1, so grandparent2 keeps a reference
-   * as well.
-   */
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &parent1, 1);
-
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_root_level_insert (void)
-{
-  GtkTreeIter grandparent1, grandparent2, grandparent3;
-  GtkTreeIter new_node;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   * + grandparent3
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
-
-  assert_node_ref_count (ref_model, &new_node, 2);
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_root_level_remove (void)
-{
-  GtkTreeIter grandparent1, grandparent2, grandparent3;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   * + grandparent3
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent1);
-
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
-
-  assert_node_ref_count (ref_model, &grandparent3, 2);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_root_level_remove_filtered (void)
-{
-  GtkTreeIter grandparent1, grandparent2, grandparent3, grandparent4;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  /* + grandparent1
-   * + grandparent2
-   * + grandparent3
-   * + grandparent4
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent4, NULL);
-
-  /* Filter first node */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 2);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent3);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 2);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent4);
-
-  /* Check level length to get root level cached again */
-  check_level_length (GTK_TREE_MODEL_FILTER (filter_model), NULL, 0);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter_model), NULL, 1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_root_level_reordered (void)
-{
-  GtkTreeIter grandparent1, grandparent2, grandparent3;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   * + grandparent3
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  /* gtk_tree_store_move() will emit rows-reordered */
-  gtk_tree_store_move_after (GTK_TREE_STORE (model),
-                             &grandparent1, &grandparent3);
-
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_root_level_reordered_filtered (void)
-{
-  GtkTreeIter grandparent1, grandparent2, grandparent3;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  /* + grandparent1
-   * + grandparent2
-   * + grandparent3
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
-
-  /* Test with 1 node filtered */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, TRUE, -1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  /* Move the invisible node grandparent1 */
-
-  /* gtk_tree_store_move() will emit rows-reordered */
-  gtk_tree_store_move_after (GTK_TREE_STORE (model),
-                             &grandparent1, &grandparent3);
-
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-
-  /* Move the invisible node grandparent1 */
-
-  /* gtk_tree_store_move() will emit rows-reordered */
-  gtk_tree_store_move_before (GTK_TREE_STORE (model),
-                              &grandparent1, &grandparent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  /* Now swap grandparent2 and grandparent3, first reference must transfer */
-  /* gtk_tree_store_swap() will emit rows-reordered */
-  gtk_tree_store_swap (GTK_TREE_STORE (model),
-                       &grandparent2, &grandparent3);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-
-  /* Swap back */
-  gtk_tree_store_swap (GTK_TREE_STORE (model),
-                       &grandparent2, &grandparent3);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-
-  /* Test with two nodes filtered */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 2);
-
-  /* gtk_tree_store_move() will emit rows-reordered */
-  gtk_tree_store_move_before (GTK_TREE_STORE (model),
-                             &grandparent3, &grandparent1);
-
-  assert_node_ref_count (ref_model, &grandparent3, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_root_level_filter (void)
-{
-  GtkTreeIter grandparent1, grandparent2, grandparent3, grandparent4;
-  GtkTreeIter new_node;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  /* + grandparent1
-   * + grandparent2
-   * + grandparent3
-   * + grandparent4
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent4, NULL);
-
-  /* Filter first node */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 2);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 2);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
-
-  assert_node_ref_count (ref_model, &new_node, 0);
-  assert_node_ref_count (ref_model, &grandparent1, 2);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &new_node, 0);
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &new_node);
-  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
-
-  assert_node_ref_count (ref_model, &new_node, 0);
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &new_node, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &new_node, 2);
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &new_node);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_child_level_insert (void)
-{
-  GtkTreeIter grandparent1;
-  GtkTreeIter parent1, parent2, parent3;
-  GtkTreeIter new_node;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   *   + parent1
-   *   + parent2
-   *   + parent3
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &grandparent1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &new_node, 1);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_child_level_remove (void)
-{
-  GtkTreeIter grandparent1;
-  GtkTreeIter parent1, parent2, parent3;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   *   + parent1
-   *   + parent2
-   *   + parent3
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent3, 1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_child_level_remove_filtered (void)
-{
-  GtkTreeIter grandparent1;
-  GtkTreeIter parent1, parent2, parent3, parent4;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  /* + grandparent1
-   *   + parent1
-   *   + parent2
-   *   + parent3
-   *   + parent4
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent4, &grandparent1);
-
-  /* Filter first node */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent1, 0, FALSE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent3, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent4, 0, TRUE, -1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &parent3, 0);
-  assert_node_ref_count (ref_model, &parent4, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent3, 1);
-  assert_node_ref_count (ref_model, &parent4, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent3);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent4, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent4);
-
-  /* Check level length to get level cached again */
-  check_level_length (GTK_TREE_MODEL_FILTER (filter_model), "0", 0);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 1);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent2, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter_model), "0", 1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_child_level_reordered (void)
-{
-  GtkTreeIter grandparent1;
-  GtkTreeIter parent1, parent2, parent3;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   *   + parent1
-   *   + parent2
-   *   + parent3
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  /* gtk_tree_store_move() will emit rows-reordered */
-  gtk_tree_store_move_after (GTK_TREE_STORE (model),
-                             &parent1, &parent3);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &parent3, 0);
-  assert_node_ref_count (ref_model, &parent1, 0);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_child_level_reordered_filtered (void)
-{
-  GtkTreeIter grandparent1;
-  GtkTreeIter parent1, parent2, parent3;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  /* + grandparent1
-   *   + parent1
-   *   + parent2
-   *   + parent3
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
-
-  /* Test with 1 node filtered (parent1) */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent3, 0, TRUE, -1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  /* Move invisible node parent 1 */
-
-  /* gtk_tree_store_move() will emit rows-reordered */
-  gtk_tree_store_move_after (GTK_TREE_STORE (model),
-                             &parent1, &parent3);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &parent3, 0);
-  assert_node_ref_count (ref_model, &parent1, 0);
-
-  /* Move invisible node parent 1 */
-
-  /* gtk_tree_store_move() will emit rows-reordered */
-  gtk_tree_store_move_before (GTK_TREE_STORE (model),
-                              &parent1, &parent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  /* Now swap parent2 and parent2, first reference must transfer */
-  /* gtk_tree_store_swap() will emit rows-reordered */
-  gtk_tree_store_swap (GTK_TREE_STORE (model),
-                       &parent2, &parent3);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent3, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-
-  /* Swap back */
-  gtk_tree_store_swap (GTK_TREE_STORE (model),
-                       &parent2, &parent3);
-
-  assert_node_ref_count (ref_model, &grandparent1, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent1, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &parent3, 0);
-
-  /* Test with two nodes filtered */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent1, 0, FALSE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &parent2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &parent3, 1);
-
-  /* gtk_tree_store_move() will emit rows-reordered */
-  gtk_tree_store_move_before (GTK_TREE_STORE (model),
-                             &parent3, &parent1);
-
-  assert_node_ref_count (ref_model, &parent3, 1);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &parent1, 0);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_transfer_child_level_filter (void)
-{
-  GtkTreeIter root;
-  GtkTreeIter grandparent1, grandparent2, grandparent3, grandparent4;
-  GtkTreeIter new_node;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  /* + root
-   *    + grandparent1
-   *    + grandparent2
-   *    + grandparent3
-   *    + grandparent4
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, &root);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, &root);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, &root);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent4, &root);
-
-  /* Filter first node */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &root, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 1);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &root);
-
-  assert_node_ref_count (ref_model, &new_node, 0);
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &new_node, 0);
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &new_node);
-  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &root);
-
-  assert_node_ref_count (ref_model, &new_node, 0);
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 1);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &new_node, 0, TRUE, -1);
-
-  assert_node_ref_count (ref_model, &new_node, 1);
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 0);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &new_node);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &grandparent3, 0);
-  assert_node_ref_count (ref_model, &grandparent4, 0);
-
-  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-
-static gboolean
-specific_path_dependent_filter_func (GtkTreeModel *model,
-                                     GtkTreeIter  *iter,
-                                     gpointer      data)
-{
-  GtkTreePath *path;
-
-  path = gtk_tree_model_get_path (model, iter);
-  if (gtk_tree_path_get_indices (path)[0] < 4)
-    return FALSE;
-
-  return TRUE;
-}
-
-static void
-specific_path_dependent_filter (void)
-{
-  int i;
-  GtkTreeIter iter;
-  GtkListStore *list;
-  GtkTreeModel *sort;
-  GtkTreeModel *filter;
-
-  list = gtk_list_store_new (1, G_TYPE_INT);
-  gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
-  gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
-  gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
-  gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
-  gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
-  gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
-  gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
-  gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
-
-  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_path_dependent_filter_func,
-                                          NULL, NULL);
-
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
-                                        GTK_SORT_DESCENDING);
-
-  for (i = 0; i < 4; i++)
-    {
-      if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
-                                         NULL, 1))
-        gtk_list_store_remove (list, &iter);
-
-      if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
-                                         NULL, 2))
-        gtk_list_store_remove (list, &iter);
-    }
-
-  g_object_unref (filter);
-  g_object_unref (sort);
-  g_object_unref (list);
-}
-
-
-static gboolean
-specific_append_after_collapse_visible_func (GtkTreeModel *model,
-                                             GtkTreeIter  *iter,
-                                             gpointer      data)
-{
-  gint number;
-  gboolean hide_negative_numbers;
-
-  gtk_tree_model_get (model, iter, 1, &number, -1);
-  hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
-
-  return (number >= 0 || !hide_negative_numbers);
-}
-
-static void
-specific_append_after_collapse (void)
-{
-  /* This test is based on one of the test cases I found in my
-   * old test cases directory.  I unfortunately do not have a record
-   * from who this test case originated.  -Kris.
-   *
-   * General idea:
-   * - Construct tree.
-   * - Show tree, expand, collapse.
-   * - Add a row.
-   */
-
-  GtkTreeIter iter;
-  GtkTreeIter child_iter;
-  GtkTreeIter child_iter2;
-  GtkTreePath *append_path;
-  GtkTreeStore *store;
-  GtkTreeModel *filter;
-  GtkTreeModel *sort;
-
-  GtkWidget *window;
-  GtkWidget *tree_view;
-
-  store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
-
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-  g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
-                     GINT_TO_POINTER (FALSE));
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_append_after_collapse_visible_func,
-                                          filter, NULL);
-
-  sort = gtk_tree_model_sort_new_with_model (filter);
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  tree_view = gtk_tree_view_new_with_model (sort);
-  gtk_container_add (GTK_CONTAINER (window), tree_view);
-  gtk_widget_realize (tree_view);
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  gtk_tree_store_prepend (store, &iter, NULL);
-  gtk_tree_store_set (store, &iter,
-                      0, "hallo", 1, 1, -1);
-
-  gtk_tree_store_append (store, &child_iter, &iter);
-  gtk_tree_store_set (store, &child_iter,
-                      0, "toemaar", 1, 1, -1);
-
-  gtk_tree_store_append (store, &child_iter2, &child_iter);
-  gtk_tree_store_set (store, &child_iter2,
-                      0, "very deep", 1, 1, -1);
-
-  append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
-
-  gtk_tree_store_append (store, &child_iter, &iter);
-  gtk_tree_store_set (store, &child_iter,
-                      0, "sja", 1, 1, -1);
-
-  gtk_tree_store_append (store, &child_iter, &iter);
-  gtk_tree_store_set (store, &child_iter,
-                      0, "some word", 1, -1, -1);
-
-  /* Expand and collapse the tree */
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  /* Add another it */
-  g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
-                     GINT_TO_POINTER (TRUE));
-
-  if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
-    {
-      gtk_tree_store_append (store, &child_iter, &iter);
-      gtk_tree_store_set (store, &child_iter,
-                          0, "new new new !!", 1, 1, -1);
-    }
-  gtk_tree_path_free (append_path);
-
-  /* Expand */
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-}
-
-
-static gint
-specific_sort_filter_remove_node_compare_func (GtkTreeModel  *model,
-                                               GtkTreeIter   *iter1,
-                                               GtkTreeIter   *iter2,
-                                               gpointer       data)
-{
-  return -1;
-}
-
-static gboolean
-specific_sort_filter_remove_node_visible_func (GtkTreeModel  *model,
-                                               GtkTreeIter   *iter,
-                                               gpointer       data)
-{
-  char *item = NULL;
-
-  /* Do reference the model */
-  gtk_tree_model_get (model, iter, 0, &item, -1);
-  g_free (item);
-
-  return FALSE;
-}
-
-static void
-specific_sort_filter_remove_node (void)
-{
-  /* This test is based on one of the test cases I found in my
-   * old test cases directory.  I unfortunately do not have a record
-   * from who this test case originated.  -Kris.
-   *
-   * General idea:
-   *  - Create tree store, sort, filter models.  The sort model has
-   *    a default sort func that is enabled, filter model a visible func
-   *    that defaults to returning FALSE.
-   *  - Remove a node from the tree store.
-   */
-
-  GtkTreeIter iter;
-  GtkTreeStore *store;
-  GtkTreeModel *filter;
-  GtkTreeModel *sort;
-
-  GtkWidget *window;
-  GtkWidget *tree_view;
-
-  store = gtk_tree_store_new (1, G_TYPE_STRING);
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
-
-  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
-  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
-                                           specific_sort_filter_remove_node_compare_func, NULL, NULL);
-
-  filter = gtk_tree_model_filter_new (sort, NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_sort_filter_remove_node_visible_func,
-                                          filter, NULL);
-
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  tree_view = gtk_tree_view_new_with_model (filter);
-  gtk_container_add (GTK_CONTAINER (window), tree_view);
-  gtk_widget_realize (tree_view);
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  /* Remove a node */
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
-  gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
-  gtk_tree_store_remove (store, &iter);
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-}
-
-
-static void
-specific_sort_filter_remove_root (void)
-{
-  /* This test is based on one of the test cases I found in my
-   * old test cases directory.  I unfortunately do not have a record
-   * from who this test case originated.  -Kris.
-   */
-
-  GtkTreeModel *model, *sort, *filter;
-  GtkTreeIter root, mid, leaf;
-  GtkTreePath *path;
-
-  model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
-  gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
-
-  path = gtk_tree_model_get_path (model, &mid);
-
-  sort = gtk_tree_model_sort_new_with_model (model);
-  filter = gtk_tree_model_filter_new (sort, path);
-
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
-
-  g_object_unref (filter);
-  g_object_unref (sort);
-  g_object_unref (model);
-}
-
-
-static void
-specific_root_mixed_visibility (void)
-{
-  int i;
-  GtkTreeModel *filter;
-  /* A bit nasty, apologies */
-  FilterTest fixture;
-
-  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-
-  for (i = 0; i < LEVEL_LENGTH; i++)
-    {
-      GtkTreeIter iter;
-
-      gtk_tree_store_insert (fixture.store, &iter, NULL, i);
-      if (i % 2 == 0)
-        create_tree_store_set_values (fixture.store, &iter, TRUE);
-      else
-        create_tree_store_set_values (fixture.store, &iter, FALSE);
-    }
-
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
-  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
-  fixture.monitor = NULL;
-
-  gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
-
-  /* In order to trigger the potential bug, we should not access
-   * the filter model here (so don't call the check functions).
-   */
-
-  /* Change visibility of an odd row to TRUE */
-  set_path_visibility (&fixture, "3", TRUE);
-  check_filter_model (&fixture);
-  check_level_length (fixture.filter, NULL, 4);
-}
-
-
-
-static gboolean
-specific_has_child_filter_filter_func (GtkTreeModel *model,
-                                       GtkTreeIter  *iter,
-                                       gpointer      data)
-{
-  return gtk_tree_model_iter_has_child (model, iter);
-}
-
-static void
-specific_has_child_filter (void)
-{
-  GtkTreeModel *filter;
-  GtkTreeIter iter, root;
-  FilterTest fixture; /* This is not how it should be done */
-  GtkWidget *tree_view;
-
-  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
-  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
-  fixture.monitor = signal_monitor_new (filter);
-
-  tree_view = gtk_tree_view_new_with_model (filter);
-
-  /* We will filter on parent state using a filter function.  We will
-   * manually keep the boolean column in sync, so that we can use
-   * check_filter_model() to check the consistency of the model.
-   */
-  /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
-   * to be able to check the structure here.  We keep the calls to
-   * check_filter_model() commented out until then.
-   */
-  gtk_tree_model_filter_set_visible_func (fixture.filter,
-                                          specific_has_child_filter_filter_func,
-                                          NULL, NULL);
-
-  /* The first node will be initially invisible: no signals */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  create_tree_store_set_values (fixture.store, &root, FALSE);
-
-  /* check_filter_model (&fixture); */
-  check_level_length (fixture.filter, NULL, 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Insert a child node. This will cause the parent to become visible
-   * since there is a child now.
-   */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  /* Parent must now be visible.  Do the level length check first,
-   * to avoid modifying the child model triggering a row-changed to
-   * the filter model.
-   */
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* This should propagate row-changed */
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  set_path_visibility (&fixture, "0", TRUE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* New root node, no child, so no signal */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  check_level_length (fixture.filter, NULL, 1);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* When the child comes in, this node will become visible */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  check_level_length (fixture.filter, NULL, 2);
-  check_level_length (fixture.filter, "1", 0);
-
-  create_tree_store_set_values (fixture.store, &root, TRUE);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Add another child for 1 */
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-  check_level_length (fixture.filter, NULL, 2);
-  check_level_length (fixture.filter, "0", 0);
-  check_level_length (fixture.filter, "1", 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Now remove one of the remaining child rows */
-  signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
-                                       &iter, "0:0");
-  gtk_tree_store_remove (fixture.store, &iter);
-
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 0);
-
-  set_path_visibility (&fixture, "0", FALSE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  g_object_unref (fixture.filter);
-  g_object_unref (fixture.store);
-  gtk_widget_destroy (tree_view);
-}
-
-
-static gboolean
-specific_root_has_child_filter_filter_func (GtkTreeModel *model,
-                                            GtkTreeIter  *iter,
-                                            gpointer      data)
-{
-  int depth;
-  GtkTreePath *path;
-
-  path = gtk_tree_model_get_path (model, iter);
-  depth = gtk_tree_path_get_depth (path);
-  gtk_tree_path_free (path);
-
-  if (depth > 1)
-    return TRUE;
-  /* else */
-  return gtk_tree_model_iter_has_child (model, iter);
-}
-
-static void
-specific_root_has_child_filter (void)
-{
-  GtkTreeModel *filter;
-  GtkTreeIter iter, root;
-  FilterTest fixture; /* This is not how it should be done ... */
-  GtkWidget *tree_view;
-
-  /* This is a variation on the above test case, specific has-child-filter,
-   * herein the has-child check for visibility only applies to root level
-   * nodes.  In this test, children are always visible because we
-   * only filter based on the "has child" criterion.
-   */
-
-  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
-  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
-  fixture.monitor = signal_monitor_new (filter);
-
-  tree_view = gtk_tree_view_new_with_model (filter);
-
-  /* We will filter on parent state using a filter function.  We will
-   * manually keep the boolean column in sync, so that we can use
-   * check_filter_model() to check the consistency of the model.
-   */
-  /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
-   * to be able to check the structure here.  We keep the calls to
-   * check_filter_model() commented out until then.
-   */
-  gtk_tree_model_filter_set_visible_func (fixture.filter,
-                                          specific_root_has_child_filter_filter_func,
-                                          NULL, NULL);
-
-  /* Add a first node, this will be invisible initially, so no signal
-   * should be emitted.
-   */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  create_tree_store_set_values (fixture.store, &root, FALSE);
-
-  signal_monitor_assert_is_empty (fixture.monitor);
-  /* check_filter_model (&fixture); */
-  check_level_length (fixture.filter, NULL, 0);
-
-  /* Add a child node.  This will cause the parent to become visible,
-   * so we expect row-inserted signals for both.
-   */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 1);
-
-  /* Modify the content of iter, no signals because the parent is not
-   * expanded.
-   */
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Parent must now be visible.  Do the level length check first,
-   * to avoid modifying the child model triggering a row-changed to
-   * the filter model.
-   */
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 1);
-
-  /* Modify path 0 */
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  set_path_visibility (&fixture, "0", TRUE);
-  /* check_filter_model (&fixture); */
-
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Insert another node in the root level.  Initially invisible, so
-   * not expecting any signal.
-   */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  check_level_length (fixture.filter, NULL, 1);
-
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Adding a child node which also makes parent at path 1 visible. */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  check_level_length (fixture.filter, NULL, 2);
-  check_level_length (fixture.filter, "1", 1);
-
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Check if row-changed is propagated */
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-
-  create_tree_store_set_values (fixture.store, &root, TRUE);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Insert another child under node 1 */
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-  check_level_length (fixture.filter, NULL, 2);
-  check_level_length (fixture.filter, "0", 1);
-  check_level_length (fixture.filter, "1", 2);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Set a child node to invisible.  This should not yield any
-   * change, because filtering is only done on whether the root
-   * node has a child, which it still has.
-   */
-  set_path_visibility (&fixture, "0:0", FALSE);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Now remove one of the remaining child rows */
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
-                                       &iter, "0:0");
-  gtk_tree_store_remove (fixture.store, &iter);
-
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 2);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Set visibility of 0 to FALSE, no-op for filter model since
-   * the child 0:0 is already gone
-   */
-  set_path_visibility (&fixture, "0", FALSE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  g_object_unref (fixture.filter);
-  g_object_unref (fixture.store);
-  gtk_widget_destroy (tree_view);
-}
-
-static void
-specific_has_child_filter_on_sort_model (void)
-{
-  GtkTreeModel *filter;
-  GtkTreeModel *sort_model;
-  GtkTreeIter iter, root;
-  FilterTest fixture; /* This is not how it should be done */
-  GtkWidget *tree_view;
-
-  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-  sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
-  filter = gtk_tree_model_filter_new (sort_model, NULL);
-  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
-  fixture.monitor = signal_monitor_new (filter);
-
-  tree_view = gtk_tree_view_new_with_model (filter);
-
-  /* We will filter on parent state using a filter function.  We will
-   * manually keep the boolean column in sync, so that we can use
-   * check_filter_model() to check the consistency of the model.
-   */
-  /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
-   * to be able to check the structure here.  We keep the calls to
-   * check_filter_model() commented out until then.
-   */
-  gtk_tree_model_filter_set_visible_func (fixture.filter,
-                                          specific_has_child_filter_filter_func,
-                                          NULL, NULL);
-
-  /* The first node will be initially invisible: no signals */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  create_tree_store_set_values (fixture.store, &root, FALSE);
-
-  /* check_filter_model (&fixture); */
-  check_level_length (fixture.filter, NULL, 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Insert a child node. This will cause the parent to become visible
-   * since there is a child now.
-   */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  /* Parent must now be visible.  Do the level length check first,
-   * to avoid modifying the child model triggering a row-changed to
-   * the filter model.
-   */
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* This should propagate row-changed */
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  set_path_visibility (&fixture, "0", TRUE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* New root node, no child, so no signal */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  check_level_length (fixture.filter, NULL, 1);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* When the child comes in, this node will become visible */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  check_level_length (fixture.filter, NULL, 2);
-  check_level_length (fixture.filter, "1", 0);
-
-  create_tree_store_set_values (fixture.store, &root, TRUE);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Add another child for 1 */
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-  check_level_length (fixture.filter, NULL, 2);
-  check_level_length (fixture.filter, "0", 0);
-  check_level_length (fixture.filter, "1", 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Now remove one of the remaining child rows */
-  signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
-                                       &iter, "0:0");
-  gtk_tree_store_remove (fixture.store, &iter);
-
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 0);
-
-  set_path_visibility (&fixture, "0", FALSE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  g_object_unref (fixture.filter);
-  g_object_unref (fixture.store);
-  gtk_widget_destroy (tree_view);
-}
-
-static gboolean
-specific_at_least_2_children_filter_filter_func (GtkTreeModel *model,
-                                                 GtkTreeIter  *iter,
-                                                 gpointer      data)
-{
-  return gtk_tree_model_iter_n_children (model, iter) >= 2;
-}
-
-static void
-specific_at_least_2_children_filter (void)
-{
-  GtkTreeModel *filter;
-  GtkTreeIter iter, root;
-  FilterTest fixture; /* This is not how it should be done */
-  GtkWidget *tree_view;
-
-  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
-  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
-  fixture.monitor = signal_monitor_new (filter);
-
-  tree_view = gtk_tree_view_new_with_model (filter);
-
-  gtk_tree_model_filter_set_visible_func (fixture.filter,
-                                          specific_at_least_2_children_filter_filter_func,
-                                          NULL, NULL);
-
-  /* The first node will be initially invisible: no signals */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  create_tree_store_set_values (fixture.store, &root, FALSE);
-
-  /* check_filter_model (&fixture); */
-  check_level_length (fixture.filter, NULL, 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Insert a child node.  Nothing should happen.
-   */
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  check_level_length (fixture.filter, NULL, 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Insert a second child node.  This will cause the parent to become
-   * visible.
-   */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  /* Parent must now be visible.  Do the level length check first,
-   * to avoid modifying the child model triggering a row-changed to
-   * the filter model.
-   */
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* This should propagate row-changed */
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  set_path_visibility (&fixture, "0", TRUE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* New root node, no child, so no signal */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  check_level_length (fixture.filter, NULL, 1);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* First child, no signal, no change */
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  check_level_length (fixture.filter, NULL, 1);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* When the second child comes in, this node will become visible */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  check_level_length (fixture.filter, NULL, 2);
-  check_level_length (fixture.filter, "1", 0);
-
-  create_tree_store_set_values (fixture.store, &root, TRUE);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Add another child for 1 */
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-  check_level_length (fixture.filter, NULL, 2);
-  check_level_length (fixture.filter, "0", 0);
-  check_level_length (fixture.filter, "1", 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Now remove one of the remaining child rows */
-  signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
-
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
-                                       &iter, "0:0");
-  gtk_tree_store_remove (fixture.store, &iter);
-
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 0);
-
-  set_path_visibility (&fixture, "0", FALSE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  g_object_unref (fixture.filter);
-  g_object_unref (fixture.store);
-  gtk_widget_destroy (tree_view);
-}
-
-static void
-specific_at_least_2_children_filter_on_sort_model (void)
-{
-  GtkTreeRowReference *ref;
-  GtkTreeModel *filter;
-  GtkTreeModel *sort_model;
-  GtkTreeIter iter, root;
-  FilterTest fixture; /* This is not how it should be done */
-  GtkWidget *tree_view;
-
-  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
-  sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
-  filter = gtk_tree_model_filter_new (sort_model, NULL);
-  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
-  fixture.monitor = signal_monitor_new (filter);
-
-  tree_view = gtk_tree_view_new_with_model (filter);
-
-  gtk_tree_model_filter_set_visible_func (fixture.filter,
-                                          specific_at_least_2_children_filter_filter_func,
-                                          NULL, NULL);
-
-  /* The first node will be initially invisible: no signals */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  create_tree_store_set_values (fixture.store, &root, FALSE);
-
-  /* check_filter_model (&fixture); */
-  check_level_length (fixture.filter, NULL, 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* Insert a child node.  Nothing should happen.
-   */
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  check_level_length (fixture.filter, NULL, 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-    {
-      GtkTreePath *path = gtk_tree_path_new_from_indices (0, 0, -1);
-
-      ref = gtk_tree_row_reference_new (sort_model, path);
-      gtk_tree_path_free (path);
-    }
-
-  /* Insert a second child node.  This will cause the parent to become
-   * visible.
-   */
-  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  gtk_tree_store_append (fixture.store, &iter, &root);
-  create_tree_store_set_values (fixture.store, &iter, TRUE);
-
-  /* Parent must now be visible.  Do the level length check first,
-   * to avoid modifying the child model triggering a row-changed to
-   * the filter model.
-   */
-  check_level_length (fixture.filter, NULL, 1);
-  check_level_length (fixture.filter, "0", 0);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* This should propagate row-changed */
-  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
-  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
-
-  set_path_visibility (&fixture, "0", TRUE);
-  /* check_filter_model (&fixture); */
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  /* New root node, no child, so no signal */
-  gtk_tree_store_append (fixture.store, &root, NULL);
-  check_level_length (fixture.filter, NULL, 1);
-  signal_monitor_assert_is_empty (fixture.monitor);
-
-  gtk_tree_row_reference_free (ref);
-  g_object_unref (fixture.filter);
-  g_object_unref (fixture.store);
-  gtk_widget_destroy (tree_view);
-}
-
-
-static void
-specific_filter_add_child (void)
-{
-  /* This test is based on one of the test cases I found in my
-   * old test cases directory.  I unfortunately do not have a record
-   * from who this test case originated.  -Kris.
-   */
-
-  GtkTreeIter iter;
-  GtkTreeIter iter_first;
-  GtkTreeIter child;
-  GtkTreeStore *store;
-  GtkTreeModel *filter G_GNUC_UNUSED;
-
-  store = gtk_tree_store_new (1, G_TYPE_STRING);
-
-  gtk_tree_store_append (store, &iter_first, NULL);
-  gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_set (store, &iter, 0, "Hello", -1);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_set (store, &iter, 0, "Hello", -1);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_set (store, &iter, 0, "Hello", -1);
-
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-
-  gtk_tree_store_set (store, &iter, 0, "Hello", -1);
-  gtk_tree_store_append (store, &child, &iter_first);
-  gtk_tree_store_set (store, &child, 0, "Hello", -1);
-}
-
-static void
-specific_list_store_clear (void)
-{
-  GtkTreeIter iter;
-  GtkListStore *list;
-  GtkTreeModel *filter;
-  GtkWidget *view G_GNUC_UNUSED;
-
-  list = gtk_list_store_new (1, G_TYPE_INT);
-  gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
-  gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
-  gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
-  gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
-  gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
-  gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
-  gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
-  gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
-
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
-  view = gtk_tree_view_new_with_model (filter);
-
-  gtk_list_store_clear (list);
-}
-
-static void
-specific_sort_ref_leaf_and_remove_ancestor (void)
-{
-  GtkTreeIter iter, child, child2, child3;
-  GtkTreeStore *tree;
-  GtkTreeModel *sort;
-  GtkTreePath *path;
-  GtkTreeRowReference *rowref;
-  GtkWidget *view G_GNUC_UNUSED;
-
-  tree = gtk_tree_store_new (1, G_TYPE_INT);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
-
-  gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
-  gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
-  gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
-
-  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
-  view = gtk_tree_view_new_with_model (sort);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
-
-  path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
-  rowref = gtk_tree_row_reference_new (sort, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
-  rowref = gtk_tree_row_reference_new (sort, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (3, 0, -1);
-  rowref = gtk_tree_row_reference_new (sort, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (3, -1);
-  rowref = gtk_tree_row_reference_new (sort, path);
-  gtk_tree_path_free (path);
-
-  /* Deleting a parent */
-  path = gtk_tree_path_new_from_indices (3, 0, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
-  gtk_tree_store_remove (tree, &iter);
-  gtk_tree_path_free (path);
-
-  gtk_tree_row_reference_free (rowref);
-}
-
-static void
-specific_ref_leaf_and_remove_ancestor (void)
-{
-  GtkTreeIter iter, child, child2, child3;
-  GtkTreeStore *tree;
-  GtkTreeModel *filter;
-  GtkTreePath *path;
-  GtkTreeRowReference *rowref;
-  GtkWidget *view G_GNUC_UNUSED;
-
-  tree = gtk_tree_store_new (1, G_TYPE_INT);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
-
-  gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
-  gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
-  gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
-
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), NULL);
-  view = gtk_tree_view_new_with_model (filter);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
-
-  path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
-  rowref = gtk_tree_row_reference_new (filter, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
-  rowref = gtk_tree_row_reference_new (filter, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (3, 0, -1);
-  rowref = gtk_tree_row_reference_new (filter, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (3, -1);
-  rowref = gtk_tree_row_reference_new (filter, path);
-  gtk_tree_path_free (path);
-
-  /* Deleting a parent */
-  path = gtk_tree_path_new_from_indices (3, 0, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
-  gtk_tree_store_remove (tree, &iter);
-  gtk_tree_path_free (path);
-
-  gtk_tree_row_reference_free (rowref);
-}
-
-static void
-specific_virtual_ref_leaf_and_remove_ancestor (void)
-{
-  GtkTreeIter iter, child, child2, child3;
-  GtkTreeStore *tree;
-  GtkTreeModel *filter;
-  GtkTreePath *path;
-  GtkTreeRowReference *rowref;
-  GtkWidget *view G_GNUC_UNUSED;
-
-  tree = gtk_tree_store_new (1, G_TYPE_INT);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
-  gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
-
-  gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
-  gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
-  gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
-
-  /* Set a virtual root of 3:0 */
-  path = gtk_tree_path_new_from_indices (3, 0, -1);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
-  gtk_tree_path_free (path);
-
-  view = gtk_tree_view_new_with_model (filter);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
-
-  path = gtk_tree_path_new_from_indices (0, 0, -1);
-  rowref = gtk_tree_row_reference_new (filter, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (0, 0, -1);
-  rowref = gtk_tree_row_reference_new (filter, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (0, -1);
-  rowref = gtk_tree_row_reference_new (filter, path);
-  gtk_tree_path_free (path);
-
-  /* Deleting the virtual root */
-  path = gtk_tree_path_new_from_indices (3, 0, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
-  gtk_tree_store_remove (tree, &iter);
-  gtk_tree_path_free (path);
-
-  gtk_tree_row_reference_free (rowref);
-}
-
-
-static int
-specific_bug_301558_sort_func (GtkTreeModel *model,
-                               GtkTreeIter  *a,
-                               GtkTreeIter  *b,
-                               gpointer      data)
-{
-  int i, j;
-
-  gtk_tree_model_get (model, a, 0, &i, -1);
-  gtk_tree_model_get (model, b, 0, &j, -1);
-
-  return j - i;
-}
-
-static void
-specific_bug_301558 (void)
-{
-  /* Test case for GNOME Bugzilla bug 301558 provided by
-   * Markku Vire.
-   */
-  GtkTreeStore *tree;
-  GtkTreeModel *filter;
-  GtkTreeModel *sort;
-  GtkTreeIter root, iter, iter2;
-  GtkWidget *view G_GNUC_UNUSED;
-  int i;
-  gboolean add;
-
-  g_test_bug ("301558");
-
-  tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
-  gtk_tree_store_append (tree, &iter, NULL);
-  gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
-  gtk_tree_store_append (tree, &iter2, &iter);
-  gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
-
-  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
-  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
-                                           specific_bug_301558_sort_func,
-                                           NULL, NULL);
-
-  filter = gtk_tree_model_filter_new (sort, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
-
-  view = gtk_tree_view_new_with_model (filter);
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  add = TRUE;
-
-  for (i = 0; i < 10; i++)
-    {
-      if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
-        g_assert_not_reached ();
-
-      if (add)
-        {
-          gtk_tree_store_append (tree, &iter, &root);
-          gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
-        }
-      else
-        {
-          int n;
-          n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
-          gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
-                                         &root, n - 1);
-          gtk_tree_store_remove (tree, &iter);
-        }
-
-      add = !add;
-    }
-}
-
-
-static gboolean
-specific_bug_311955_filter_func (GtkTreeModel *model,
-                                 GtkTreeIter  *iter,
-                                 gpointer      data)
-{
-  int value;
-
-  gtk_tree_model_get (model, iter, 0, &value, -1);
-
-  return (value != 0);
-}
-
-static void
-specific_bug_311955 (void)
-{
-  /* This is a test case for GNOME Bugzilla bug 311955.  It was written
-   * by Markku Vire.
-   */
-  GtkTreeIter iter, child, root;
-  GtkTreeStore *store;
-  GtkTreeModel *sort;
-  GtkTreeModel *filter;
-
-  GtkWidget *window G_GNUC_UNUSED;
-  GtkWidget *tree_view;
-  int i;
-  int n;
-  GtkTreePath *path;
-
-  g_test_bug ("311955");
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_append (store, &root, NULL);
-  gtk_tree_store_set (store, &root, 0, 33, -1);
-
-  gtk_tree_store_append (store, &iter, &root);
-  gtk_tree_store_set (store, &iter, 0, 50, -1);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_set (store, &iter, 0, 22, -1);
-
-  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
-  filter = gtk_tree_model_filter_new (sort, NULL);
-
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_bug_311955_filter_func,
-                                          NULL, NULL);
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  tree_view = gtk_tree_view_new_with_model (filter);
-  g_object_unref (store);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
-
-  /* Fill model */
-  for (i = 0; i < 4; i++)
-    {
-      gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
-
-      gtk_tree_store_append (store, &iter, &root);
-
-      if (i < 3)
-        gtk_tree_store_set (store, &iter, 0, i, -1);
-
-      if (i % 2 == 0)
-        {
-          gtk_tree_store_append (store, &child, &iter);
-          gtk_tree_store_set (store, &child, 0, 10, -1);
-        }
-    }
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 1);
-
-  /* Remove bottommost child from the tree. */
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
-  n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
-
-  if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
-    {
-      if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
-        gtk_tree_store_remove (store, &child);
-    }
-  else
-    g_assert_not_reached ();
-
-  path = gtk_tree_path_new_from_indices (0, 2, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-  gtk_tree_path_free (path);
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
-}
-
-static void
-specific_bug_311955_clean (void)
-{
-  /* Cleaned up version of the test case for GNOME Bugzilla bug 311955,
-   * which is easier to understand.
-   */
-  GtkTreeIter iter, child, grandchild;
-  GtkTreeStore *store;
-  GtkTreeModel *sort;
-  GtkTreeModel *filter;
-
-  GtkWidget *tree_view;
-  GtkTreePath *path;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_set (store, &iter, 0, 1, -1);
-
-  gtk_tree_store_append (store, &child, &iter);
-  gtk_tree_store_set (store, &child, 0, 1, -1);
-
-  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
-  filter = gtk_tree_model_filter_new (sort, NULL);
-
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_bug_311955_filter_func,
-                                          NULL, NULL);
-
-  tree_view = gtk_tree_view_new_with_model (filter);
-  g_object_unref (store);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
-
-  gtk_tree_store_append (store, &child, &iter);
-  gtk_tree_store_set (store, &child, 0, 0, -1);
-
-  gtk_tree_store_append (store, &child, &iter);
-  gtk_tree_store_set (store, &child, 0, 1, -1);
-
-  gtk_tree_store_append (store, &child, &iter);
-  gtk_tree_store_set (store, &child, 0, 1, -1);
-
-  gtk_tree_store_append (store, &grandchild, &child);
-  gtk_tree_store_set (store, &grandchild, 0, 1, -1);
-
-  gtk_tree_store_append (store, &child, &iter);
-  /* Don't set a value: assume 0 */
-
-  /* Remove leaf node, check trigger row-has-child-toggled */
-  path = gtk_tree_path_new_from_indices (0, 3, 0, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
-  gtk_tree_path_free (path);
-  gtk_tree_store_remove (store, &iter);
-
-  path = gtk_tree_path_new_from_indices (0, 2, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-  gtk_tree_path_free (path);
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
-
-  gtk_widget_destroy (tree_view);
-}
-
-static void
-specific_bug_346800 (void)
-{
-  /* This is a test case for GNOME Bugzilla bug 346800.  It was written
-   * by Jonathan Matthew.
-   */
-
-  GtkTreeIter node_iters[50];
-  GtkTreeIter child_iters[50];
-  GtkTreeModel *model;
-  GtkTreeModelFilter *filter;
-  GtkTreeStore *store;
-  GType *columns;
-  int i;
-  int items = 50;
-  columns = g_new (GType, 2);
-  columns[0] = G_TYPE_STRING;
-  columns[1] = G_TYPE_BOOLEAN;
-  store = gtk_tree_store_newv (2, columns);
-  model = GTK_TREE_MODEL (store);
-
-  g_test_bug ("346800");
-
-  filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
-  gtk_tree_model_filter_set_visible_column (filter, 1);
-
-  for (i=0; i<items; i++)
-    {
-      /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
-
-      g_malloc (138);
-      gtk_tree_store_append (store, &node_iters[i], NULL);
-      gtk_tree_store_set (store, &node_iters[i],
-                          0, "something",
-                          1, ((i%6) == 0) ? FALSE : TRUE,
-                          -1);
-
-      g_malloc (47);
-      gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
-      gtk_tree_store_set (store, &child_iters[i],
-                          0, "something else",
-                          1, FALSE,
-                          -1);
-      gtk_tree_model_filter_refilter (filter);
-
-      if (i > 6)
-        {
-          gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
-                              (i & 1) ? TRUE : FALSE, -1);
-          gtk_tree_model_filter_refilter (filter);
-
-          gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
-                              (i & 1) ? FALSE: TRUE, -1);
-          gtk_tree_model_filter_refilter (filter);
-        }
-    }
-}
-
-static gboolean
-specific_bug_464173_visible_func (GtkTreeModel *model,
-                                  GtkTreeIter  *iter,
-                                  gpointer      data)
-{
-  gboolean *visible = (gboolean *)data;
-
-  return *visible;
-}
-
-static void
-specific_bug_464173 (void)
-{
-  /* Test case for GNOME Bugzilla bug 464173, test case written
-   * by Andreas Koehler.
-   */
-  GtkTreeStore *model;
-  GtkTreeModelFilter *f_model;
-  GtkTreeIter iter1, iter2;
-  GtkWidget *view G_GNUC_UNUSED;
-  gboolean visible = TRUE;
-
-  g_test_bug ("464173");
-
-  model = gtk_tree_store_new (1, G_TYPE_STRING);
-  gtk_tree_store_append (model, &iter1, NULL);
-  gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
-  gtk_tree_store_append (model, &iter2, &iter1);
-  gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
-
-  f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
-  gtk_tree_model_filter_set_visible_func (f_model,
-                                          specific_bug_464173_visible_func,
-                                          &visible, NULL);
-
-  view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
-
-  visible = FALSE;
-  gtk_tree_model_filter_refilter (f_model);
-}
-
-
-static gboolean
-specific_bug_540201_filter_func (GtkTreeModel *model,
-                                 GtkTreeIter  *iter,
-                                 gpointer      data)
-{
-  gboolean has_children;
-
-  has_children = gtk_tree_model_iter_has_child (model, iter);
-
-  return has_children;
-}
-
-static void
-specific_bug_540201 (void)
-{
-  /* Test case for GNOME Bugzilla bug 540201, steps provided by
-   * Charles Day.
-   */
-  GtkTreeIter iter, root;
-  GtkTreeStore *store;
-  GtkTreeModel *filter;
-
-  GtkWidget *tree_view G_GNUC_UNUSED;
-
-  g_test_bug ("540201");
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_append (store, &root, NULL);
-  gtk_tree_store_set (store, &root, 0, 33, -1);
-
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-  tree_view = gtk_tree_view_new_with_model (filter);
-
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_bug_540201_filter_func,
-                                          NULL, NULL);
-
-  gtk_tree_store_append (store, &iter, &root);
-  gtk_tree_store_set (store, &iter, 0, 50, -1);
-
-  gtk_tree_store_append (store, &iter, &root);
-  gtk_tree_store_set (store, &iter, 0, 22, -1);
-
-
-  gtk_tree_store_append (store, &root, NULL);
-  gtk_tree_store_set (store, &root, 0, 33, -1);
-
-  gtk_tree_store_append (store, &iter, &root);
-  gtk_tree_store_set (store, &iter, 0, 22, -1);
-}
-
-
-static gboolean
-specific_bug_549287_visible_func (GtkTreeModel *model,
-                                  GtkTreeIter  *iter,
-                                  gpointer      data)
-{
-  gboolean result = FALSE;
-
-  result = gtk_tree_model_iter_has_child (model, iter);
-
-  return result;
-}
-
-static void
-specific_bug_549287 (void)
-{
-  /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
-
-  int i;
-  GtkTreeStore *store;
-  GtkTreeModel *filtered;
-  GtkWidget *view G_GNUC_UNUSED;
-  GtkTreeIter iter;
-  GtkTreeIter *swap, *parent, *child;
-
-  g_test_bug ("529287");
-
-  store = gtk_tree_store_new (1, G_TYPE_STRING);
-  filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
-                                          specific_bug_549287_visible_func,
-                                          NULL, NULL);
-
-  view = gtk_tree_view_new_with_model (filtered);
-
-  for (i = 0; i < 4; i++)
-    {
-      if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
-        {
-          parent = gtk_tree_iter_copy (&iter);
-          child = gtk_tree_iter_copy (&iter);
-
-          while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
-                                                child, parent, 0))
-            {
-
-              swap = parent;
-              parent = child;
-              child = swap;
-            }
-
-          gtk_tree_store_append (store, child, parent);
-          gtk_tree_store_set (store, child,
-                              0, "Something",
-                              -1);
-
-          gtk_tree_iter_free (parent);
-          gtk_tree_iter_free (child);
-        }
-      else
-        {
-          gtk_tree_store_append (store, &iter, NULL);
-          gtk_tree_store_set (store, &iter,
-                              0, "Something",
-                              -1);
-        }
-
-      /* since we inserted something, we changed the visibility conditions: */
-      gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
-    }
-}
-
-static gboolean
-specific_bug_621076_visible_func (GtkTreeModel *model,
-                                  GtkTreeIter  *iter,
-                                  gpointer      data)
-{
-  gboolean visible = FALSE;
-  gchar *str = NULL;
-
-  gtk_tree_model_get (model, iter, 0, &str, -1);
-  if (str != NULL && g_str_has_prefix (str, "visible"))
-    {
-      visible = TRUE;
-    }
-  else
-    {
-      GtkTreeIter child_iter;
-      gboolean valid;
-
-      /* Recursively check if we have a visible child */
-      for (valid = gtk_tree_model_iter_children (model, &child_iter, iter);
-           valid; valid = gtk_tree_model_iter_next (model, &child_iter))
-        {
-          if (specific_bug_621076_visible_func (model, &child_iter, data))
-            {
-              visible = TRUE;
-              break;
-            }
-        }
-    }
-
-  if (str)
-    g_free (str);
-
-  return visible;
-}
-
-static void
-specific_bug_621076 (void)
-{
-  /* Test case for GNOME Bugzilla bug 621076, provided by Xavier Claessens */
-
-  /* This test case differs from has-child-filter and root-has-child-filter
-   * in that the visible function both filters on content and model
-   * structure.  Also, it is recursive.
-   */
-
-  GtkTreeStore *store;
-  GtkTreeModel *filter;
-  GtkWidget *view;
-  GtkTreeIter group_iter;
-  GtkTreeIter item_iter;
-  SignalMonitor *monitor;
-
-  g_test_bug ("621076");
-
-  store = gtk_tree_store_new (1, G_TYPE_STRING);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_bug_621076_visible_func,
-                                          NULL, NULL);
-
-  view = gtk_tree_view_new_with_model (filter);
-  g_object_ref_sink (view);
-
-  monitor = signal_monitor_new (filter);
-
-  signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
-  gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
-                                     0, "visible-group-0",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* visible-group-0 is not expanded, so ROW_INSERTED should not be emitted
-   * for its children. However, ROW_HAS_CHILD_TOGGLED should be emitted on
-   * visible-group-0 to tell the view that row can be expanded. */
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
-  group_iter = item_iter;
-  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
-                                     0, "visible-0:0",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  signal_monitor_append_signal (monitor, ROW_INSERTED, "1");
-  gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
-                                     0, "visible-group-1",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* We are adding an hidden item inside visible-group-1, so
-   * ROW_HAS_CHILD_TOGGLED should not be emitted.  It is emitted though,
-   * because the signal originating at TreeStore will be propagated,
-   * as well a generated signal because the state of the parent *could*
-   * change by a change in the model.
-   */
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  group_iter = item_iter;
-  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
-                                     0, "group-1:0",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* This group is invisible and its parent too. Nothing should be emitted */
-  group_iter = item_iter;
-  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
-                                     0, "group-1:0:0",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* Adding a visible item in this group hierarchy will make all nodes
-   * in this path visible.  The first level should simply tell the view
-   * that it now has a child, and the view will load the tree if needed
-   * (depends on the expanded state).
-   */
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  group_iter = item_iter;
-  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
-                                     0, "visible-1:0:0:0",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  check_level_length (GTK_TREE_MODEL_FILTER (filter), "1", 1);
-
-  gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
-                                     0, "group-2",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* Parent is invisible, and adding this invisible item won't change that,
-   * so no signal should be emitted. */
-  group_iter = item_iter;
-  gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
-                                     0, "invisible-2:0",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* This makes group-2 visible, so it gets inserted and tells it has
-   * children.
-   */
-  signal_monitor_append_signal (monitor, ROW_INSERTED, "2");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
-                                     0, "visible-2:1",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* group-2 is already visible, so this time it is a normal insertion */
-  gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
-                                     0, "visible-2:2",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-
-  gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
-                                     0, "group-3",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* Parent is invisible, and adding this invisible item won't change that,
-   * so no signal should be emitted. */
-  group_iter = item_iter;
-  gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
-                                     0, "invisible-3:0",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
-                                     0, "invisible-3:1",
-                                     -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* This will make group 3 visible. */
-  signal_monitor_append_signal (monitor, ROW_INSERTED, "3");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
-  gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* Make sure all groups are expanded, so the filter has the tree cached */
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  /* Should only yield a row-changed */
-  signal_monitor_append_signal (monitor, ROW_CHANGED, "3:0");
-  gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* Now remove/hide some items. If a group loses its last item, the group
-   * should be deleted instead of the item.
-   */
-
-  signal_monitor_append_signal (monitor, ROW_DELETED, "2:1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:2");
-  gtk_tree_store_remove (store, &item_iter);
-  signal_monitor_assert_is_empty (monitor);
-
-  signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  signal_monitor_append_signal (monitor, ROW_DELETED, "2");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:1");
-  gtk_tree_store_set (store, &item_iter, 0, "invisible-2:1", -1);
-  signal_monitor_assert_is_empty (monitor);
-
-  signal_monitor_append_signal (monitor, ROW_DELETED, "1:0:0:0");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1:0:0");
-  signal_monitor_append_signal (monitor, ROW_DELETED, "1:0");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "1:0:0:0");
-  gtk_tree_store_remove (store, &item_iter);
-  signal_monitor_assert_is_empty (monitor);
-
-  /* Hide a group using row-changed instead of row-deleted */
-  /* Caution: group 2 is gone, so offsets of the signals have moved. */
-  signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
-  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
-  signal_monitor_append_signal (monitor, ROW_DELETED, "2");
-  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter,
-                                       "3:1");
-  gtk_tree_store_set (store, &item_iter, 0, "invisible-3:1", -1);
-  signal_monitor_assert_is_empty (monitor);
-
-#if 0
-  {
-    GtkWidget *window;
-    GtkTreeViewColumn *col;
-
-    gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
-
-    col = gtk_tree_view_column_new_with_attributes ("foo",
-        gtk_cell_renderer_text_new (),
-        "text", 0, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
-
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    g_signal_connect (window, "delete-event",
-        G_CALLBACK (gtk_widget_destroy), NULL);
-    g_signal_connect (window, "destroy",
-        G_CALLBACK (gtk_main_quit), NULL);
-
-    gtk_container_add (GTK_CONTAINER (window), view);
-
-    gtk_widget_show (view);
-    gtk_widget_show (window);
-
-    gtk_main ();
-  }
-#endif
-
-  /* Cleanup */
-  signal_monitor_free (monitor);
-  g_object_unref (view);
-  g_object_unref (store);
-  g_object_unref (filter);
-}
-
-static void
-specific_bug_657353_related (void)
-{
-  GtkTreeIter node1, node2, node3, node4;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *filter_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_BOOLEAN };
-
-  /* gtk_tree_model_filter_rows_reordered() used to have a problem to
-   * not properly transfer the first ref count when the first node in
-   * the level does not have elt->offset == 0.  This test checks for
-   * that.  This bug could cause the faulty condition
-   *   elt->ext_ref_count > elt->ref_count
-   * to raise.
-   */
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &node1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &node2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &node3, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &node4, NULL);
-
-  /* Hide the first node */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &node1, 0, FALSE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &node2, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &node3, 0, TRUE, -1);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &node4, 0, TRUE, -1);
-
-  filter_model = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  assert_node_ref_count (ref_model, &node1, 0);
-  assert_node_ref_count (ref_model, &node2, 2);
-  assert_node_ref_count (ref_model, &node3, 1);
-  assert_node_ref_count (ref_model, &node4, 1);
-
-  /* Swap nodes 2 and 3 */
-
-  /* gtk_tree_store_swap() will emit rows-reordered */
-  gtk_tree_store_swap (GTK_TREE_STORE (model),
-                       &node2, &node3);
-
-  assert_node_ref_count (ref_model, &node1, 0);
-  assert_node_ref_count (ref_model, &node3, 2);
-  assert_node_ref_count (ref_model, &node2, 1);
-  assert_node_ref_count (ref_model, &node4, 1);
-
-  /* Hide node 3 */
-  gtk_tree_store_set (GTK_TREE_STORE (model), &node3, 0, FALSE, -1);
-
-  assert_node_ref_count (ref_model, &node1, 0);
-  assert_node_ref_count (ref_model, &node3, 0);
-  assert_node_ref_count (ref_model, &node2, 2);
-  assert_node_ref_count (ref_model, &node4, 1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (ref_model);
-}
-
-static gboolean
-specific_bug_657353_visible_func (GtkTreeModel *model,
-                                  GtkTreeIter  *iter,
-                                  gpointer      data)
-{
-  gchar *str;
-  gboolean ret = FALSE;
-
-  gtk_tree_model_get (model, iter, 0, &str, -1);
-  ret = strstr (str, "hidden") ? FALSE : TRUE;
-  g_free (str);
-
-  return ret;
-}
-
-static void
-specific_bug_657353 (void)
-{
-  GtkListStore *store;
-  GtkTreeModel *sort_model;
-  GtkTreeModel *filter_model;
-  GtkTreeIter iter, iter_a, iter_b, iter_c;
-  GtkWidget *tree_view;
-
-  /* This is a very carefully crafted test case that is triggering the
-   * situation described in bug 657353.
-   *
-   *   GtkListStore acts like EphyCompletionModel
-   *   GtkTreeModelSort acts like the sort model added in
-   *                      ephy_location_entry_set_completion.
-   *   GtkTreeModelFilter acts like the filter model in
-   *                      GtkEntryCompletion.
-   */
-
-  /* Set up a model that's wrapped in a GtkTreeModelSort.  The first item
-   * will be hidden.
-   */
-  store = gtk_list_store_new (1, G_TYPE_STRING);
-  gtk_list_store_insert_with_values (store, &iter_b, 0, 0, "BBB hidden", -1);
-  gtk_list_store_insert_with_values (store, &iter, 1, 0, "EEE", -1);
-  gtk_list_store_insert_with_values (store, &iter, 2, 0, "DDD", -1);
-  gtk_list_store_insert_with_values (store, &iter_c, 3, 0, "CCC", -1);
-
-  sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
-
-  filter_model = gtk_tree_model_filter_new (sort_model, NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model),
-                                          specific_bug_657353_visible_func,
-                                          filter_model, NULL);
-
-  tree_view = gtk_tree_view_new_with_model (filter_model);
-
-  /* This triggers emission of rows-reordered.  The elt with offset == 0
-   * is hidden, which used to cause misbehavior.  (The first reference should
-   * have moved to CCC, which did not happen).
-   */
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_ASCENDING);
-
-  /* By inserting another item that will appear at the first position, a
-   * reference transfer is done from CCC (which failed to get this reference
-   * earlier) to AAA.  At this point, the rule
-   * elt->ref_count >= elt->ext_ref_count is broken for CCC.
-   */
-  gtk_list_store_insert_with_values (store, &iter_a, 6, 0, "AAA", -1);
-
-  /* When we hide CCC, the references cannot be correctly released, because
-   * CCC failed to get a reference during rows-reordered.  The faulty condition
-   * only manifests itself here with MODEL_FILTER_DEBUG disabled (as is usual
-   * in production).
-   */
-  gtk_list_store_set (store, &iter_c, 0, "CCC hidden", -1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter_model);
-  g_object_unref (sort_model);
-  g_object_unref (store);
-}
-
-static void
-specific_bug_658696 (void)
-{
-  GtkTreeStore *store;
-  GtkTreeModel *filter;
-  GtkTreePath *vroot;
-  GtkTreeIter iter;
-
-  store = create_tree_store (4, TRUE);
-
-  vroot = gtk_tree_path_new_from_indices (0, 0, -1);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), vroot);
-  gtk_tree_path_free (vroot);
-
-  /* This used to cause a crash in gtk_tree_model_filter_check_ancestors() */
-  gtk_tree_store_append (store, &iter, NULL);
-
-  g_object_unref (store);
-  g_object_unref (filter);
-}
-
-static gboolean
-specific_bug_659022_visible_func (GtkTreeModel *model,
-                                  GtkTreeIter  *iter,
-                                  gpointer      data)
-{
-  GtkTreeIter tmp;
-
-  if (!gtk_tree_model_iter_parent (model, &tmp, iter))
-    {
-      if (gtk_tree_model_iter_n_children (model, iter) >= 2)
-        return TRUE;
-      else
-        return FALSE;
-    }
-
-  return TRUE;
-}
-
-static void
-specific_bug_659022_row_changed_emission (void)
-{
-  GtkTreeModel *filter;
-  GtkTreeModel *model;
-  GtkTreeIter parent, child, child2;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-
-  filter = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_bug_659022_visible_func,
-                                          NULL, NULL);
-
-  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (filter));
-
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent, NULL, 0);
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &child, &parent, 0);
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &child2, &parent, 0);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter));
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
-
-  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter));
-
-  path = gtk_tree_model_get_path (model, &child);
-  gtk_tree_model_row_changed (model, path, &child);
-  gtk_tree_path_free (path);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter);
-  g_object_unref (model);
-}
-
-static void
-specific_bug_659022_row_deleted_node_invisible (void)
-{
-  GtkTreeModel *filter;
-  GtkTreeModel *model;
-  GtkTreeIter parent, child;
-  GtkTreeIter parent2, child2, child3;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-
-  filter = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_bug_659022_visible_func,
-                                          NULL, NULL);
-
-  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (filter));
-
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent, NULL, 0);
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &child, &parent, 0);
-
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent2, NULL, 0);
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &child2, &parent2, 0);
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &child3, &parent2, 0);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter));
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter);
-  g_object_unref (model);
-}
-
-static void
-specific_bug_659022_row_deleted_free_level (void)
-{
-  GtkTreeModel *filter;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeIter parent, child;
-  GtkTreeIter parent2, child2, child3;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  filter = gtk_tree_model_filter_new (model, NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
-                                          specific_bug_659022_visible_func,
-                                          NULL, NULL);
-
-  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (filter));
-
-  /* Carefully construct a model */
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent, NULL, 0);
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &child, &parent, 0);
-
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent2, NULL, 0);
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &child2, &parent2, 0);
-  gtk_tree_store_insert (GTK_TREE_STORE (model), &child3, &parent2, 0);
-
-  /* Only parent2 is visible, child3 holds first ref count for that level
-   * (Note that above, both child2 as child3 are inserted at position 0).
-   */
-  assert_node_ref_count (ref_model, &parent, 0);
-  assert_node_ref_count (ref_model, &child, 0);
-  assert_node_ref_count (ref_model, &parent2, 3);
-  assert_node_ref_count (ref_model, &child3, 1);
-  assert_node_ref_count (ref_model, &child2, 0);
-
-  /* Make sure child level is cached */
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &parent, 0);
-  assert_node_ref_count (ref_model, &child, 0);
-  assert_node_ref_count (ref_model, &parent2, 3);
-  assert_node_ref_count (ref_model, &child3, 2);
-  assert_node_ref_count (ref_model, &child2, 1);
-
-  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &parent, 0);
-  assert_node_ref_count (ref_model, &child, 0);
-  assert_node_ref_count (ref_model, &parent2, 3);
-  assert_node_ref_count (ref_model, &child3, 1);
-  assert_node_ref_count (ref_model, &child2, 0);
-
-  /* Remove node with longer child level first */
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (filter);
-  g_object_unref (model);
-}
-
-static void
-specific_bug_679910 (void)
-{
-  GtkTreeModel *filter;
-  GtkListStore *store;
-  GtkTreeIter iter, nil_iter;
-  GtkTreeIter filter_iter;
-
-  store = gtk_list_store_new (1, G_TYPE_POINTER);
-  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-
-  gtk_list_store_append (store, &nil_iter);
-  gtk_list_store_append (store, &iter);
-  gtk_list_store_append (store, &nil_iter);
-
-  gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (filter),
-                                                    &filter_iter,
-                                                    &iter);
-  iter = filter_iter;
-  g_return_if_fail (gtk_tree_model_iter_next (filter, &iter));
-  iter = filter_iter;
-  g_return_if_fail (gtk_tree_model_iter_previous (filter, &iter));
-
-  g_object_unref (filter);
-  g_object_unref (store);
-}
-
-/* main */
-
-void
-register_filter_model_tests (void)
-{
-  g_test_add ("/TreeModelFilter/self/verify-test-suite",
-              FilterTest, NULL,
-              filter_test_setup,
-              verify_test_suite,
-              filter_test_teardown);
-
-  g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-1",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup,
-              verify_test_suite_vroot,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-2",
-              FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
-              filter_test_setup,
-              verify_test_suite_vroot,
-              filter_test_teardown);
-
-
-  g_test_add ("/TreeModelFilter/filled/hide-root-level",
-              FilterTest, NULL,
-              filter_test_setup,
-              filled_hide_root_level,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filled/hide-child-levels",
-              FilterTest, NULL,
-              filter_test_setup,
-              filled_hide_child_levels,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filled/hide-child-levels/root-expanded",
-              FilterTest, NULL,
-              filter_test_setup,
-              filled_hide_child_levels_root_expanded,
-              filter_test_teardown);
-
-  g_test_add ("/TreeModelFilter/filled/hide-root-level/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup,
-              filled_vroot_hide_root_level,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup,
-              filled_vroot_hide_child_levels,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot-root-expanded",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup,
-              filled_vroot_hide_child_levels_root_expanded,
-              filter_test_teardown);
-
-
-  g_test_add ("/TreeModelFilter/empty/show-nodes",
-              FilterTest, NULL,
-              filter_test_setup_empty,
-              empty_show_nodes,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/empty/show-multiple-nodes",
-              FilterTest, NULL,
-              filter_test_setup_empty,
-              empty_show_multiple_nodes,
-              filter_test_teardown);
-
-  g_test_add ("/TreeModelFilter/empty/show-nodes/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_empty,
-              empty_vroot_show_nodes,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/empty/show-multiple-nodes/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_empty,
-              empty_vroot_show_multiple_nodes,
-              filter_test_teardown);
-
-
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single",
-              FilterTest, NULL,
-              filter_test_setup_unfiltered,
-              unfiltered_hide_single,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single/root-expanded",
-              FilterTest, NULL,
-              filter_test_setup_unfiltered_root_expanded,
-              unfiltered_hide_single_root_expanded,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single-child",
-              FilterTest, NULL,
-              filter_test_setup_unfiltered,
-              unfiltered_hide_single_child,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/root-expanded",
-              FilterTest, NULL,
-              filter_test_setup_unfiltered_root_expanded,
-              unfiltered_hide_single_child_root_expanded,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level",
-              FilterTest, NULL,
-              filter_test_setup_unfiltered,
-              unfiltered_hide_single_multi_level,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/root-expanded",
-              FilterTest, NULL,
-              filter_test_setup_unfiltered_root_expanded,
-              unfiltered_hide_single_multi_level_root_expanded,
-              filter_test_teardown);
-
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_unfiltered,
-              unfiltered_vroot_hide_single,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_unfiltered,
-              unfiltered_vroot_hide_single_child,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot/root-expanded",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_unfiltered_root_expanded,
-              unfiltered_vroot_hide_single_child_root_expanded,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_unfiltered,
-              unfiltered_vroot_hide_single_multi_level,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot/root-expanded",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_unfiltered_root_expanded,
-              unfiltered_vroot_hide_single_multi_level_root_expanded,
-              filter_test_teardown);
-
-
-
-  g_test_add ("/TreeModelFilter/unfiltered/show-single",
-              FilterTest, NULL,
-              filter_test_setup_empty_unfiltered,
-              unfiltered_show_single,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/show-single-child",
-              FilterTest, NULL,
-              filter_test_setup_empty_unfiltered,
-              unfiltered_show_single_child,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/show-single-child/root-expanded",
-              FilterTest, NULL,
-              filter_test_setup_empty_unfiltered_root_expanded,
-              unfiltered_show_single_child_root_expanded,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level",
-              FilterTest, NULL,
-              filter_test_setup_empty_unfiltered,
-              unfiltered_show_single_multi_level,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/root-expanded",
-              FilterTest, NULL,
-              filter_test_setup_empty_unfiltered_root_expanded,
-              unfiltered_show_single_multi_level_root_expanded,
-              filter_test_teardown);
-
-  g_test_add ("/TreeModelFilter/unfiltered/show-single/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_empty_unfiltered,
-              unfiltered_vroot_show_single,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_empty_unfiltered,
-              unfiltered_vroot_show_single_child,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot/root-expanded",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_empty_unfiltered_root_expanded,
-              unfiltered_vroot_show_single_child_root_expanded,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_empty_unfiltered,
-              unfiltered_vroot_show_single_multi_level,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot/root-expanded",
-              FilterTest, gtk_tree_path_new_from_indices (2, -1),
-              filter_test_setup_empty_unfiltered_root_expanded,
-              unfiltered_vroot_show_single_multi_level_root_expanded,
-              filter_test_teardown);
-
-
-  g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/root-level",
-              FilterTest, NULL,
-              filter_test_setup_unfiltered,
-              unfiltered_rows_reordered_root_level,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/child-level",
-              FilterTest, NULL,
-              filter_test_setup_unfiltered,
-              unfiltered_rows_reordered_child_level,
-              filter_test_teardown);
-
-  g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/first-hidden",
-              FilterTest, NULL,
-              filter_test_setup,
-              filtered_rows_reordered_root_level_first_hidden,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/middle-hidden",
-              FilterTest, NULL,
-              filter_test_setup,
-              filtered_rows_reordered_root_level_middle_hidden,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/first-hidden",
-              FilterTest, NULL,
-              filter_test_setup,
-              filtered_rows_reordered_child_level_first_hidden,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/middle-hidden",
-              FilterTest, NULL,
-              filter_test_setup,
-              filtered_rows_reordered_child_level_middle_hidden,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/4-hidden",
-              FilterTest, NULL,
-              filter_test_setup,
-              filtered_rows_reordered_child_level_4_hidden,
-              filter_test_teardown);
-  g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/all-hidden",
-              FilterTest, NULL,
-              filter_test_setup,
-              filtered_rows_reordered_child_level_all_hidden,
-              filter_test_teardown);
-
-  /* Inserts in child models after creation of filter model */
-  g_test_add_func ("/TreeModelFilter/insert/before",
-                   insert_before);
-  g_test_add_func ("/TreeModelFilter/insert/child",
-                   insert_child);
-
-  /* Removals from child model after creating of filter model */
-  g_test_add_func ("/TreeModelFilter/remove/node",
-                   remove_node);
-  g_test_add_func ("/TreeModelFilter/remove/node-vroot",
-                   remove_node_vroot);
-  g_test_add_func ("/TreeModelFilter/remove/vroot-ancestor",
-                   remove_vroot_ancestor);
-
-  /* Reference counting */
-  g_test_add_func ("/TreeModelFilter/ref-count/single-level",
-                   ref_count_single_level);
-  g_test_add_func ("/TreeModelFilter/ref-count/two-levels",
-                   ref_count_two_levels);
-  g_test_add_func ("/TreeModelFilter/ref-count/three-levels",
-                   ref_count_three_levels);
-  g_test_add_func ("/TreeModelFilter/ref-count/delete-row",
-                   ref_count_delete_row);
-  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-1",
-                   ref_count_filter_row_length_1);
-  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-1-remove-in-root-level",
-                   ref_count_filter_row_length_1_remove_in_root_level);
-  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-1-remove-in-child-level",
-                   ref_count_filter_row_length_1_remove_in_child_level);
-  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-gt-1",
-                   ref_count_filter_row_length_gt_1);
-  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-gt-1-visible-children",
-                   ref_count_filter_row_length_gt_1_visible_children);
-  g_test_add_func ("/TreeModelFilter/ref-count/cleanup",
-                   ref_count_cleanup);
-  g_test_add_func ("/TreeModelFilter/ref-count/row-ref",
-                   ref_count_row_ref);
-
-  /* Reference counting, transfer of first reference on
-   * first node in level.  This is a GtkTreeModelFilter-specific
-   * feature.
-   */
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/insert",
-                   ref_count_transfer_root_level_insert);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/remove",
-                   ref_count_transfer_root_level_remove);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/remove/filtered",
-                   ref_count_transfer_root_level_remove_filtered);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/reordered",
-                   ref_count_transfer_root_level_reordered);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/reordered/filtered",
-                   ref_count_transfer_root_level_reordered_filtered);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/filter",
-                   ref_count_transfer_root_level_filter);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/insert",
-                   ref_count_transfer_child_level_insert);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/remove",
-                   ref_count_transfer_child_level_remove);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/remove/filtered",
-                   ref_count_transfer_child_level_remove_filtered);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/reordered",
-                   ref_count_transfer_child_level_reordered);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/reordered/filtered",
-                   ref_count_transfer_child_level_reordered_filtered);
-  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/filter",
-                   ref_count_transfer_child_level_filter);
-
-  g_test_add_func ("/TreeModelFilter/specific/path-dependent-filter",
-                   specific_path_dependent_filter);
-  g_test_add_func ("/TreeModelFilter/specific/append-after-collapse",
-                   specific_append_after_collapse);
-  g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-node",
-                   specific_sort_filter_remove_node);
-  g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-root",
-                   specific_sort_filter_remove_root);
-  g_test_add_func ("/TreeModelFilter/specific/root-mixed-visibility",
-                   specific_root_mixed_visibility);
-  g_test_add_func ("/TreeModelFilter/specific/has-child-filter",
-                   specific_has_child_filter);
-  g_test_add_func ("/TreeModelFilter/specific/has-child-filter-on-sort-model",
-                   specific_has_child_filter_on_sort_model);
-  g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter",
-                   specific_at_least_2_children_filter);
-  g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter-on-sort-model",
-                   specific_at_least_2_children_filter_on_sort_model);
-  g_test_add_func ("/TreeModelFilter/specific/root-has-child-filter",
-                   specific_root_has_child_filter);
-  g_test_add_func ("/TreeModelFilter/specific/filter-add-child",
-                   specific_filter_add_child);
-  g_test_add_func ("/TreeModelFilter/specific/list-store-clear",
-                   specific_list_store_clear);
-  g_test_add_func ("/TreeModelFilter/specific/sort-ref-leaf-and-remove-ancestor",
-                   specific_sort_ref_leaf_and_remove_ancestor);
-  g_test_add_func ("/TreeModelFilter/specific/ref-leaf-and-remove-ancestor",
-                   specific_ref_leaf_and_remove_ancestor);
-  g_test_add_func ("/TreeModelFilter/specific/virtual-ref-leaf-and-remove-ancestor",
-                   specific_virtual_ref_leaf_and_remove_ancestor);
-
-  g_test_add_func ("/TreeModelFilter/specific/bug-301558",
-                   specific_bug_301558);
-  g_test_add_func ("/TreeModelFilter/specific/bug-311955",
-                   specific_bug_311955);
-  g_test_add_func ("/TreeModelFilter/specific/bug-311955-clean",
-                   specific_bug_311955_clean);
-  g_test_add_func ("/TreeModelFilter/specific/bug-346800",
-                   specific_bug_346800);
-  g_test_add_func ("/TreeModelFilter/specific/bug-464173",
-                   specific_bug_464173);
-  g_test_add_func ("/TreeModelFilter/specific/bug-540201",
-                   specific_bug_540201);
-  g_test_add_func ("/TreeModelFilter/specific/bug-549287",
-                   specific_bug_549287);
-  g_test_add_func ("/TreeModelFilter/specific/bug-621076",
-                   specific_bug_621076);
-  g_test_add_func ("/TreeModelFilter/specific/bug-657353-related",
-                   specific_bug_657353_related);
-  g_test_add_func ("/TreeModelFilter/specific/bug-657353",
-                   specific_bug_657353);
-  g_test_add_func ("/TreeModelFilter/specific/bug-658696",
-                   specific_bug_658696);
-  g_test_add_func ("/TreeModelFilter/specific/bug-659022/row-changed-emission",
-                   specific_bug_659022_row_changed_emission);
-  g_test_add_func ("/TreeModelFilter/specific/bug-659022/row-deleted-node-invisible",
-                   specific_bug_659022_row_deleted_node_invisible);
-  g_test_add_func ("/TreeModelFilter/specific/bug-659022/row-deleted-free-level",
-                   specific_bug_659022_row_deleted_free_level);
-  g_test_add_func ("/TreeModelFilter/specific/bug-679910",
-                   specific_bug_679910);
-}
diff --git a/gtk/tests/floating.c b/gtk/tests/floating.c
deleted file mode 100644 (file)
index 89add67..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* floatingtest.c - test floating flag uses
- * Copyright (C) 2005 Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <gtk/gtk.h>
-
-static gboolean destroyed = FALSE;
-static void
-destroy (void)
-{
-  destroyed = TRUE;
-}
-
-static void
-floating_tests (void)
-{
-  GtkWidget *widget = g_object_new (GTK_TYPE_LABEL, NULL);
-  g_object_connect (widget, "signal::destroy", destroy, NULL, NULL);
-
-  g_assert (g_object_is_floating (widget));
-
-  g_object_ref_sink (widget);
-  g_assert (!g_object_is_floating (widget));
-
-  g_object_force_floating (G_OBJECT (widget));
-  g_assert (g_object_is_floating (widget));
-
-  g_object_ref_sink (widget);
-  g_assert (!g_object_is_floating (widget));
-
-  g_assert (!destroyed);
-  g_object_unref (widget);
-  g_assert (destroyed);
-}
-
-int
-main (int   argc,
-      char *argv[])
-{
-  gtk_test_init (&argc, &argv);
-  g_test_add_func ("/floatingtest", floating_tests);
-  return g_test_run();
-}
diff --git a/gtk/tests/grid.c b/gtk/tests/grid.c
deleted file mode 100644 (file)
index 436cfa3..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2011 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-/* test that attach_next_to picks the places
- * we expect it to pick, when there is any choice
- */
-static void
-test_attach (void)
-{
-  GtkGrid *g;
-  GtkWidget *child, *sibling, *z, *A, *B;
-  gint left, top, width, height;
-
-  g = (GtkGrid *)gtk_grid_new ();
-
-  child = gtk_label_new ("a");
-  gtk_grid_attach_next_to (g, child, NULL, GTK_POS_LEFT, 1, 1);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, -1);
-  g_assert_cmpint (top,    ==, 0);
-  g_assert_cmpint (width,  ==, 1);
-  g_assert_cmpint (height, ==, 1);
-
-  sibling = child;
-  child = gtk_label_new ("b");
-  gtk_grid_attach_next_to (g, child, sibling, GTK_POS_RIGHT, 2, 2);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 0);
-  g_assert_cmpint (top,    ==, 0);
-  g_assert_cmpint (width,  ==, 2);
-  g_assert_cmpint (height, ==, 2);
-
-  /* this one should just be ignored */
-  z = gtk_label_new ("z");
-  gtk_grid_attach (g, z, 4, 4, 1, 1);
-
-  child = gtk_label_new ("c");
-  gtk_grid_attach_next_to (g, child, sibling, GTK_POS_BOTTOM, 3, 1);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, -1);
-  g_assert_cmpint (top,    ==, 1);
-  g_assert_cmpint (width,  ==, 3);
-  g_assert_cmpint (height, ==, 1);
-
-  child = gtk_label_new ("u");
-  gtk_grid_attach_next_to (g, child, z, GTK_POS_LEFT, 2, 1);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 2);
-  g_assert_cmpint (top,    ==, 4);
-  g_assert_cmpint (width,  ==, 2);
-  g_assert_cmpint (height, ==, 1);
-
-  child = gtk_label_new ("v");
-  gtk_grid_attach_next_to (g, child, z, GTK_POS_RIGHT, 2, 1);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 5);
-  g_assert_cmpint (top,    ==, 4);
-  g_assert_cmpint (width,  ==, 2);
-  g_assert_cmpint (height, ==, 1);
-
-  child = gtk_label_new ("x");
-  gtk_grid_attach_next_to (g, child, z, GTK_POS_TOP, 1, 2);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 4);
-  g_assert_cmpint (top,    ==, 2);
-  g_assert_cmpint (width,  ==, 1);
-  g_assert_cmpint (height, ==, 2);
-
-  child = gtk_label_new ("x");
-  gtk_grid_attach_next_to (g, child, z, GTK_POS_TOP, 1, 2);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 4);
-  g_assert_cmpint (top,    ==, 2);
-  g_assert_cmpint (width,  ==, 1);
-  g_assert_cmpint (height, ==, 2);
-
-  child = gtk_label_new ("y");
-  gtk_grid_attach_next_to (g, child, z, GTK_POS_BOTTOM, 1, 2);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 4);
-  g_assert_cmpint (top,    ==, 5);
-  g_assert_cmpint (width,  ==, 1);
-  g_assert_cmpint (height, ==, 2);
-
-  A = gtk_label_new ("A");
-  gtk_grid_attach (g, A, 10, 10, 1, 1);
-  B = gtk_label_new ("B");
-  gtk_grid_attach (g, B, 10, 12, 1, 1);
-
-  child  = gtk_label_new ("D");
-  gtk_grid_attach_next_to (g, child, A, GTK_POS_RIGHT, 1, 3);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 11);
-  g_assert_cmpint (top,    ==, 10);
-  g_assert_cmpint (width,  ==,  1);
-  g_assert_cmpint (height, ==,  3);
-}
-
-static void
-test_add (void)
-{
-  GtkGrid *g;
-  GtkWidget *child;
-  gint left, top, width, height;
-
-  g = (GtkGrid *)gtk_grid_new ();
-
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (g), GTK_ORIENTATION_HORIZONTAL);
-
-  child = gtk_label_new ("a");
-  gtk_container_add (GTK_CONTAINER (g), child);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 0);
-  g_assert_cmpint (top,    ==, 0);
-  g_assert_cmpint (width,  ==, 1);
-  g_assert_cmpint (height, ==, 1);
-
-  child = gtk_label_new ("b");
-  gtk_container_add (GTK_CONTAINER (g), child);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 1);
-  g_assert_cmpint (top,    ==, 0);
-  g_assert_cmpint (width,  ==, 1);
-  g_assert_cmpint (height, ==, 1);
-
-  child = gtk_label_new ("c");
-  gtk_container_add (GTK_CONTAINER (g), child);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 2);
-  g_assert_cmpint (top,    ==, 0);
-  g_assert_cmpint (width,  ==, 1);
-  g_assert_cmpint (height, ==, 1);
-
-  gtk_orientable_set_orientation (GTK_ORIENTABLE (g), GTK_ORIENTATION_VERTICAL);
-
-  child = gtk_label_new ("d");
-  gtk_container_add (GTK_CONTAINER (g), child);
-  gtk_container_child_get (GTK_CONTAINER (g), child,
-                           "left-attach", &left,
-                           "top-attach", &top,
-                           "width", &width,
-                           "height", &height,
-                           NULL);
-  g_assert_cmpint (left,   ==, 0);
-  g_assert_cmpint (top,    ==, 1);
-  g_assert_cmpint (width,  ==, 1);
-  g_assert_cmpint (height, ==, 1);
-}
-
-int
-main (int   argc,
-      char *argv[])
-{
-  gtk_test_init (&argc, &argv);
-
-  g_test_add_func ("/grid/attach", test_attach);
-  g_test_add_func ("/grid/add", test_add);
-
-  return g_test_run();
-}
diff --git a/gtk/tests/gtkmenu.c b/gtk/tests/gtkmenu.c
deleted file mode 100644 (file)
index e2667ba..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-#include <gtk/gtk.h>
-
-/* TestItem {{{1 */
-
-/* This utility struct is used by both the RandomMenu and MirrorMenu
- * class implementations below.
- */
-typedef struct {
-  GHashTable *attributes;
-  GHashTable *links;
-} TestItem;
-
-static TestItem *
-test_item_new (GHashTable *attributes,
-               GHashTable *links)
-{
-  TestItem *item;
-
-  item = g_slice_new (TestItem);
-  item->attributes = g_hash_table_ref (attributes);
-  item->links = g_hash_table_ref (links);
-
-  return item;
-}
-
-static void
-test_item_free (gpointer data)
-{
-  TestItem *item = data;
-
-  g_hash_table_unref (item->attributes);
-  g_hash_table_unref (item->links);
-
-  g_slice_free (TestItem, item);
-}
-
-/* RandomMenu {{{1 */
-#define MAX_ITEMS 10
-#define TOP_ORDER 4
-
-typedef struct {
-  GMenuModel parent_instance;
-
-  GSequence *items;
-  gint order;
-} RandomMenu;
-
-typedef GMenuModelClass RandomMenuClass;
-
-static GType random_menu_get_type (void);
-G_DEFINE_TYPE (RandomMenu, random_menu, G_TYPE_MENU_MODEL);
-
-static gboolean
-random_menu_is_mutable (GMenuModel *model)
-{
-  return TRUE;
-}
-
-static gint
-random_menu_get_n_items (GMenuModel *model)
-{
-  RandomMenu *menu = (RandomMenu *) model;
-
-  return g_sequence_get_length (menu->items);
-}
-
-static void
-random_menu_get_item_attributes (GMenuModel  *model,
-                                 gint         position,
-                                 GHashTable **table)
-{
-  RandomMenu *menu = (RandomMenu *) model;
-  TestItem *item;
-
-  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
-  *table = g_hash_table_ref (item->attributes);
-}
-
-static void
-random_menu_get_item_links (GMenuModel  *model,
-                            gint         position,
-                            GHashTable **table)
-{
-  RandomMenu *menu = (RandomMenu *) model;
-  TestItem *item;
-
-  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
-  *table = g_hash_table_ref (item->links);
-}
-
-static void
-random_menu_finalize (GObject *object)
-{
-  RandomMenu *menu = (RandomMenu *) object;
-
-  g_sequence_free (menu->items);
-
-  G_OBJECT_CLASS (random_menu_parent_class)
-    ->finalize (object);
-}
-
-static void
-random_menu_init (RandomMenu *menu)
-{
-}
-
-static void
-random_menu_class_init (GMenuModelClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-  class->is_mutable = random_menu_is_mutable;
-  class->get_n_items = random_menu_get_n_items;
-  class->get_item_attributes = random_menu_get_item_attributes;
-  class->get_item_links = random_menu_get_item_links;
-
-  object_class->finalize = random_menu_finalize;
-}
-
-static RandomMenu * random_menu_new (GRand *rand, gint order);
-
-static void
-random_menu_change (RandomMenu *menu,
-                    GRand      *rand)
-{
-  gint position, removes, adds;
-  GSequenceIter *point;
-  gint n_items;
-  gint i;
-
-  n_items = g_sequence_get_length (menu->items);
-
-  do
-    {
-      position = g_rand_int_range (rand, 0, n_items + 1);
-      removes = g_rand_int_range (rand, 0, n_items - position + 1);
-      adds = g_rand_int_range (rand, 0, MAX_ITEMS - (n_items - removes) + 1);
-    }
-  while (removes == 0 && adds == 0);
-
-  point = g_sequence_get_iter_at_pos (menu->items, position + removes);
-
-  if (removes)
-    {
-      GSequenceIter *start;
-
-      start = g_sequence_get_iter_at_pos (menu->items, position);
-      g_sequence_remove_range (start, point);
-    }
-
-  for (i = 0; i < adds; i++)
-    {
-      const gchar *label;
-      GHashTable *links;
-      GHashTable *attributes;
-
-      attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
-      links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
-
-      if (menu->order > 0 && g_rand_boolean (rand))
-        {
-          RandomMenu *child;
-          const gchar *subtype;
-
-          child = random_menu_new (rand, menu->order - 1);
-
-          if (g_rand_boolean (rand))
-            {
-              subtype = G_MENU_LINK_SECTION;
-              /* label some section headers */
-              if (g_rand_boolean (rand))
-                label = "Section";
-              else
-                label = NULL;
-            }
-          else
-            {
-              /* label all submenus */
-              subtype = G_MENU_LINK_SUBMENU;
-              label = "Submenu";
-            }
-
-          g_hash_table_insert (links, g_strdup (subtype), child);
-        }
-      else
-        /* label all terminals */
-        label = "Menu Item";
-
-      if (label)
-        g_hash_table_insert (attributes, g_strdup ("label"), g_variant_ref_sink (g_variant_new_string (label)));
-
-      g_sequence_insert_before (point, test_item_new (attributes, links));
-      g_hash_table_unref (links);
-      g_hash_table_unref (attributes);
-    }
-
-  g_menu_model_items_changed (G_MENU_MODEL (menu), position, removes, adds);
-}
-
-static RandomMenu *
-random_menu_new (GRand *rand,
-                 gint   order)
-{
-  RandomMenu *menu;
-
-  menu = g_object_new (random_menu_get_type (), NULL);
-  menu->items = g_sequence_new (test_item_free);
-  menu->order = order;
-
-  random_menu_change (menu, rand);
-
-  return menu;
-}
-
-/* Test cases {{{1 */
-
-static void assert_menu_equality (GtkContainer *container, GMenuModel   *model);
-
-static const gchar *
-get_label (GtkMenuItem *item)
-{
-  GList *children = gtk_container_get_children (GTK_CONTAINER (item));
-  const gchar *label = NULL;
-
-  while (children)
-    {
-      if (GTK_IS_CONTAINER (children->data))
-        children = g_list_concat (children, gtk_container_get_children (children->data));
-      else if (GTK_IS_LABEL (children->data))
-        label = gtk_label_get_text (children->data);
-
-      children = g_list_delete_link (children, children);
-    }
-
-  return label;
-}
-
-/* a bit complicated with the separators...
- *
- * with_separators are if subsections of this GMenuModel should have
- * separators inserted between them (ie: in the same sense as the
- * 'with_separators' argument to gtk_menu_shell_bind_model().
- *
- * needs_separator is true if this particular section needs to have a
- * separator before it in the case that it is non-empty.  this will be
- * defined for all subsections of a with_separators menu (except the
- * first) or in case section_header is non-%NULL.
- *
- * section_header is the label that must be inside that separator, if it
- * exists.  section_header is only non-%NULL if needs_separator is also
- * TRUE.
- */
-static void
-assert_section_equality (GSList      **children,
-                         gboolean      with_separators,
-                         gboolean      needs_separator,
-                         const gchar  *section_header,
-                         GMenuModel   *model)
-{
-  gboolean has_separator;
-  GSList *our_children;
-  gint i, n;
-
-  /* Assuming that we have the possibility of showing a separator, there
-   * are two valid situations:
-   *
-   *  - we have a separator and we have other children
-   *
-   *  - we have no separator and no children
-   *
-   * If we see a separator, we suppose that it is ours and that we will
-   * encounter children.  In the case that we have no children, the
-   * separator may not be ours but may rather belong to a later section.
-   *
-   * We therefore keep our own copy of the children GSList.  If we
-   * encounter children, we will delete the links that this section is
-   * responsible for and update the pass-by-reference value.  Otherwise,
-   * we will leave everything alone and let the separator be accounted
-   * for by a following section.
-   */
-  our_children = *children;
-  if (needs_separator && GTK_IS_SEPARATOR_MENU_ITEM (our_children->data))
-    {
-       /* We accounted for the separator, at least for now, so remove it
-       * from the list.
-       *
-       * We will check later if we should have actually had a separator
-       * and compare the result to has_separator.
-       */
-      our_children = our_children->next;
-      has_separator = TRUE;
-    }
-  else
-    has_separator = FALSE;
-
-  /* Now, iterate the model checking that the items in the GSList line
-   * up with our expectations. */
-  n = g_menu_model_get_n_items (model);
-  for (i = 0; i < n; i++)
-    {
-      GMenuModel *subsection;
-      GMenuModel *submenu;
-      gchar *label = NULL;
-
-      subsection = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
-      submenu = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);
-      g_menu_model_get_item_attribute (model, i, G_MENU_ATTRIBUTE_LABEL, "s", &label);
-
-      if (subsection)
-        {
-          g_assert (!submenu);
-          assert_section_equality (&our_children,
-                                   FALSE,                                /* with_separators */
-                                   label || (with_separators && i > 0),  /* needs_separator */
-                                   label,                                /* section_header */
-                                   subsection);
-          g_object_unref (subsection);
-        }
-      else
-        {
-          GtkWidget *submenu_widget;
-          GtkMenuItem *item;
-
-          /* This is a normal item.  Make sure the label is right. */
-          item = our_children->data;
-          our_children = g_slist_remove (our_children, item);
-
-          /* get_label() returns "" when it ought to return NULL */
-          g_assert_cmpstr (get_label (item), ==, label ? label : "");
-          submenu_widget = gtk_menu_item_get_submenu (item);
-
-          if (submenu)
-            {
-              g_assert (submenu_widget != NULL);
-              assert_menu_equality (GTK_CONTAINER (submenu_widget), submenu);
-              g_object_unref (submenu);
-            }
-          else
-            g_assert (!submenu_widget);
-        }
-
-      g_free (label);
-    }
-
-  /* If we found a separator but visited no children then the separator
-   * was not for us.  Patch that up.
-   */
-  if (has_separator && our_children == (*children)->next)
-    {
-      /* Rewind our_children to put the separator we tentatively
-       * consumed back into the list.
-       */
-      our_children = *children;
-      has_separator = FALSE;
-    }
-
-  if (our_children == *children)
-    /* If we had no children then we didn't really need a separator. */
-    needs_separator = FALSE;
-
-  g_assert (needs_separator == has_separator);
-
-  if (has_separator)
-    {
-      GtkWidget *contents;
-      const gchar *label;
-
-      /* We needed and had a separator and we visited a child.
-       *
-       * Make sure that separator was valid.
-       */
-      contents = gtk_bin_get_child ((*children)->data);
-      if (GTK_IS_LABEL (contents))
-        label = gtk_label_get_label (GTK_LABEL (contents));
-      else
-        label = "";
-
-      /* get_label() returns "" when it ought to return NULL */
-      g_assert_cmpstr (label, ==, section_header ? section_header : "");
-
-      /* our_children has already gone (possibly far) past *children, so
-       * we need to free up the link that we left behind for the
-       * separator in case we wanted to rewind.
-       */
-      g_slist_free_1 (*children);
-    }
-
-  *children = our_children;
-}
-
-/* We want to use a GSList here instead of a GList because the ->prev
- * pointer updates cause trouble with the way we speculatively deal with
- * separators by skipping over them and coming back to clean up later.
- */
-static void
-get_children_into_slist (GtkWidget *widget,
-                         gpointer   user_data)
-{
-  GSList **list_ptr = user_data;
-
-  *list_ptr = g_slist_prepend (*list_ptr, widget);
-}
-
-static void
-assert_menu_equality (GtkContainer *container,
-                      GMenuModel   *model)
-{
-  GSList *children = NULL;
-
-  gtk_container_foreach (container, get_children_into_slist, &children);
-  children = g_slist_reverse (children);
-
-  assert_section_equality (&children, TRUE, FALSE, NULL, model);
-  g_assert (children == NULL);
-}
-
-static void
-test_bind_menu (void)
-{
-  RandomMenu *model;
-  GtkWidget *menu;
-  GRand *rand;
-  gint i;
-
-  gtk_init (0, 0);
-
-  rand = g_rand_new_with_seed (g_test_rand_int ());
-  model = random_menu_new (rand, TOP_ORDER);
-  menu = gtk_menu_new_from_model (G_MENU_MODEL (model));
-  g_object_ref_sink (menu);
-  assert_menu_equality (GTK_CONTAINER (menu), G_MENU_MODEL (model));
-  for (i = 0; i < 100; i++)
-    {
-      random_menu_change (model, rand);
-      while (g_main_context_iteration (NULL, FALSE));
-      assert_menu_equality (GTK_CONTAINER (menu), G_MENU_MODEL (model));
-    }
-  g_object_unref (model);
-  g_object_unref (menu);
-  g_rand_free (rand);
-}
-/* Epilogue {{{1 */
-int
-main (int argc, char **argv)
-{
-  g_test_init (&argc, &argv, NULL);
-
-  g_test_add_func ("/gmenu/bind", test_bind_menu);
-
-  return g_test_run ();
-}
-/* vim:set foldmethod=marker: */
diff --git a/gtk/tests/gtktreemodelrefcount.c b/gtk/tests/gtktreemodelrefcount.c
deleted file mode 100644 (file)
index 7f29f99..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/* gtktreemodelrefcount.c
- * Copyright (C) 2011  Kristian Rietveld <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-#include "gtktreemodelrefcount.h"
-
-
-/* The purpose of this GtkTreeModel is to keep record of the reference count
- * of each node.  The reference count does not effect the functioning of
- * the model in any way.  Because this model is a subclass of GtkTreeStore,
- * the GtkTreeStore API should be used to add to and remove nodes from
- * this model.  We depend on the iter format of GtkTreeStore, which means
- * that this model needs to be revised in case the iter format of
- * GtkTreeStore is modified.  Currently, we make use of the fact that
- * the value stored in the user_data field is unique for each node.
- */
-
-struct _GtkTreeModelRefCountPrivate
-{
-  GHashTable *node_hash;
-};
-
-typedef struct
-{
-  int ref_count;
-}
-NodeInfo;
-
-
-static void      gtk_tree_model_ref_count_tree_model_init (GtkTreeModelIface *iface);
-static void      gtk_tree_model_ref_count_finalize        (GObject           *object);
-
-static NodeInfo *node_info_new                            (void);
-static void      node_info_free                           (NodeInfo          *info);
-
-/* GtkTreeModel interface */
-static void      gtk_tree_model_ref_count_ref_node        (GtkTreeModel      *model,
-                                                           GtkTreeIter       *iter);
-static void      gtk_tree_model_ref_count_unref_node      (GtkTreeModel      *model,
-                                                           GtkTreeIter       *iter);
-
-
-G_DEFINE_TYPE_WITH_CODE (GtkTreeModelRefCount, gtk_tree_model_ref_count, GTK_TYPE_TREE_STORE,
-                         G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
-                                                gtk_tree_model_ref_count_tree_model_init))
-
-static void
-row_removed (GtkTreeModelRefCount *ref_model,
-             GtkTreePath *path)
-{
-  GHashTableIter iter;
-  GtkTreeIter tree_iter;
-
-  if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ref_model), &tree_iter))
-    {
-      g_hash_table_remove_all (ref_model->priv->node_hash);
-      return;
-    }
-
-  g_hash_table_iter_init (&iter, ref_model->priv->node_hash);
-
-  while (g_hash_table_iter_next (&iter, &tree_iter.user_data, NULL))
-    {
-      if (!gtk_tree_store_iter_is_valid (GTK_TREE_STORE (ref_model), &tree_iter))
-        g_hash_table_iter_remove (&iter);
-    }
-}
-
-static void
-gtk_tree_model_ref_count_init (GtkTreeModelRefCount *ref_model)
-{
-  ref_model->priv = G_TYPE_INSTANCE_GET_PRIVATE (ref_model,
-                                                 GTK_TYPE_TREE_MODEL_REF_COUNT,
-                                                 GtkTreeModelRefCountPrivate);
-
-  ref_model->priv->node_hash = g_hash_table_new_full (g_direct_hash,
-                                                      g_direct_equal,
-                                                      NULL,
-                                                      (GDestroyNotify)node_info_free);
-
-  g_signal_connect (ref_model, "row-deleted", G_CALLBACK (row_removed), NULL);
-}
-
-static void
-gtk_tree_model_ref_count_class_init (GtkTreeModelRefCountClass *ref_model_class)
-{
-  GObjectClass *object_class;
-
-  object_class = (GObjectClass *) ref_model_class;
-
-  object_class->finalize = gtk_tree_model_ref_count_finalize;
-
-  g_type_class_add_private (object_class, sizeof (GtkTreeModelRefCountPrivate));
-}
-
-static void
-gtk_tree_model_ref_count_tree_model_init (GtkTreeModelIface *iface)
-{
-  iface->ref_node = gtk_tree_model_ref_count_ref_node;
-  iface->unref_node = gtk_tree_model_ref_count_unref_node;
-}
-
-static void
-gtk_tree_model_ref_count_finalize (GObject *object)
-{
-  GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (object);
-
-  if (ref_model->priv->node_hash)
-    {
-      g_hash_table_destroy (ref_model->priv->node_hash);
-      ref_model->priv->node_hash = NULL;
-    }
-
-  G_OBJECT_CLASS (gtk_tree_model_ref_count_parent_class)->finalize (object);
-}
-
-
-static NodeInfo *
-node_info_new (void)
-{
-  NodeInfo *info = g_slice_new (NodeInfo);
-  info->ref_count = 0;
-
-  return info;
-}
-
-static void
-node_info_free (NodeInfo *info)
-{
-  g_slice_free (NodeInfo, info);
-}
-
-static void
-gtk_tree_model_ref_count_ref_node (GtkTreeModel *model,
-                                   GtkTreeIter  *iter)
-{
-  NodeInfo *info;
-  GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
-  if (!info)
-    {
-      info = node_info_new ();
-
-      g_hash_table_insert (ref_model->priv->node_hash, iter->user_data, info);
-    }
-
-  info->ref_count++;
-}
-
-static void
-gtk_tree_model_ref_count_unref_node (GtkTreeModel *model,
-                                     GtkTreeIter  *iter)
-{
-  NodeInfo *info;
-  GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
-  g_assert (info != NULL);
-  g_assert (info->ref_count > 0);
-
-  info->ref_count--;
-}
-
-
-GtkTreeModel *
-gtk_tree_model_ref_count_new (void)
-{
-  GtkTreeModel *retval;
-
-  retval = g_object_new (gtk_tree_model_ref_count_get_type (), NULL);
-
-  return retval;
-}
-
-static void
-dump_iter (GtkTreeModelRefCount *ref_model,
-           GtkTreeIter          *iter)
-{
-  gchar *path_str;
-  NodeInfo *info;
-  GtkTreePath *path;
-
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (ref_model), iter);
-  path_str = gtk_tree_path_to_string (path);
-  gtk_tree_path_free (path);
-
-  info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
-  if (!info)
-    g_print ("%-16s ref_count=0\n", path_str);
-  else
-    g_print ("%-16s ref_count=%d\n", path_str, info->ref_count);
-
-  g_free (path_str);
-}
-
-static void
-gtk_tree_model_ref_count_dump_recurse (GtkTreeModelRefCount *ref_model,
-                                       GtkTreeIter          *iter)
-{
-  do
-    {
-      GtkTreeIter child;
-
-      dump_iter (ref_model, iter);
-
-      if (gtk_tree_model_iter_children (GTK_TREE_MODEL (ref_model),
-                                        &child, iter))
-        gtk_tree_model_ref_count_dump_recurse (ref_model, &child);
-    }
-  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ref_model), iter));
-}
-
-void
-gtk_tree_model_ref_count_dump (GtkTreeModelRefCount *ref_model)
-{
-  GtkTreeIter iter;
-
-  if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ref_model), &iter))
-    return;
-
-  gtk_tree_model_ref_count_dump_recurse (ref_model, &iter);
-}
-
-static gboolean
-check_iter (GtkTreeModelRefCount *ref_model,
-            GtkTreeIter          *iter,
-            gint                  expected_ref_count,
-            gboolean              may_assert)
-{
-  NodeInfo *info;
-
-  if (may_assert)
-    g_assert (gtk_tree_store_iter_is_valid (GTK_TREE_STORE (ref_model), iter));
-
-  info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
-  if (!info)
-    {
-      if (expected_ref_count == 0)
-        return TRUE;
-      else
-        {
-          if (may_assert)
-            g_error ("Expected ref count %d, but node has never been referenced.\n", expected_ref_count);
-          return FALSE;
-        }
-    }
-
-  if (may_assert)
-    {
-      if (expected_ref_count == 0)
-        g_assert_cmpint (expected_ref_count, ==, info->ref_count);
-      else
-        g_assert_cmpint (expected_ref_count, <=, info->ref_count);
-    }
-
-  return expected_ref_count == info->ref_count;
-}
-
-gboolean
-gtk_tree_model_ref_count_check_level (GtkTreeModelRefCount *ref_model,
-                                      GtkTreeIter          *parent,
-                                      gint                  expected_ref_count,
-                                      gboolean              recurse,
-                                      gboolean              may_assert)
-{
-  GtkTreeIter iter;
-
-  if (!gtk_tree_model_iter_children (GTK_TREE_MODEL (ref_model),
-                                     &iter, parent))
-    return TRUE;
-
-  do
-    {
-      if (!check_iter (ref_model, &iter, expected_ref_count, may_assert))
-        return FALSE;
-
-      if (recurse &&
-          gtk_tree_model_iter_has_child (GTK_TREE_MODEL (ref_model), &iter))
-        {
-          if (!gtk_tree_model_ref_count_check_level (ref_model, &iter,
-                                                     expected_ref_count,
-                                                     recurse, may_assert))
-            return FALSE;
-        }
-    }
-  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ref_model), &iter));
-
-  return TRUE;
-}
-
-gboolean
-gtk_tree_model_ref_count_check_node (GtkTreeModelRefCount *ref_model,
-                                     GtkTreeIter          *iter,
-                                     gint                  expected_ref_count,
-                                     gboolean              may_assert)
-{
-  return check_iter (ref_model, iter, expected_ref_count, may_assert);
-}
diff --git a/gtk/tests/gtktreemodelrefcount.h b/gtk/tests/gtktreemodelrefcount.h
deleted file mode 100644 (file)
index a4b4011..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* gtktreemodelrefcount.h
- * Copyright (C) 2011  Kristian Rietveld <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GTK_TREE_MODEL_REF_COUNT_H__
-#define __GTK_TREE_MODEL_REF_COUNT_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_TREE_MODEL_REF_COUNT              (gtk_tree_model_ref_count_get_type ())
-#define GTK_TREE_MODEL_REF_COUNT(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCount))
-#define GTK_TREE_MODEL_REF_COUNT_CLASS(vtable)     (G_TYPE_CHECK_CLASS_CAST ((vtable), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCountClass))
-#define GTK_IS_TREE_MODEL_REF_COUNT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT))
-#define GTK_IS_TREE_MODEL_REF_COUNT_CLASS(vtable)  (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_TYPE_TREE_MODEL_REF_COUNT))
-#define GTK_TREE_MODEL_REF_COUNT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCountClass))
-
-
-typedef struct _GtkTreeModelRefCount        GtkTreeModelRefCount;
-typedef struct _GtkTreeModelRefCountClass   GtkTreeModelRefCountClass;
-typedef struct _GtkTreeModelRefCountPrivate GtkTreeModelRefCountPrivate;
-
-struct _GtkTreeModelRefCount
-{
-  GtkTreeStore parent;
-
-  /* < private > */
-  GtkTreeModelRefCountPrivate *priv;
-};
-
-struct _GtkTreeModelRefCountClass
-{
-  GtkTreeStoreClass parent_class;
-};
-
-
-GType         gtk_tree_model_ref_count_get_type    (void) G_GNUC_CONST;
-GtkTreeModel *gtk_tree_model_ref_count_new         (void);
-
-void          gtk_tree_model_ref_count_dump        (GtkTreeModelRefCount *ref_model);
-gboolean      gtk_tree_model_ref_count_check_level (GtkTreeModelRefCount *ref_model,
-                                                    GtkTreeIter          *parent,
-                                                    gint                  expected_ref_count,
-                                                    gboolean              recurse,
-                                                    gboolean              may_assert);
-gboolean      gtk_tree_model_ref_count_check_node  (GtkTreeModelRefCount *ref_model,
-                                                    GtkTreeIter          *iter,
-                                                    gint                  expected_ref_count,
-                                                    gboolean              may_assert);
-
-/* A couple of helpers for the tests.  Since this model will never be used
- * outside of unit tests anyway, it is probably fine to have these here
- * without namespacing.
- */
-
-static inline void
-assert_entire_model_unreferenced (GtkTreeModelRefCount *ref_model)
-{
-  gtk_tree_model_ref_count_check_level (ref_model, NULL, 0, TRUE, TRUE);
-}
-
-static inline void
-assert_root_level_unreferenced (GtkTreeModelRefCount *ref_model)
-{
-  gtk_tree_model_ref_count_check_level (ref_model, NULL, 0, FALSE, TRUE);
-}
-
-static inline void
-assert_level_unreferenced (GtkTreeModelRefCount *ref_model,
-                           GtkTreeIter          *iter)
-{
-  gtk_tree_model_ref_count_check_level (ref_model, iter, 0, FALSE, TRUE);
-}
-
-static inline void
-assert_entire_model_referenced (GtkTreeModelRefCount *ref_model,
-                                gint                  ref_count)
-{
-  gtk_tree_model_ref_count_check_level (ref_model, NULL, ref_count, TRUE, TRUE);
-}
-
-static inline void
-assert_not_entire_model_referenced (GtkTreeModelRefCount *ref_model,
-                                    gint                  ref_count)
-{
-  g_assert_cmpint (gtk_tree_model_ref_count_check_level (ref_model, NULL,
-                                                         ref_count,
-                                                         TRUE, FALSE),
-                   ==, FALSE);
-}
-
-static inline void
-assert_root_level_referenced (GtkTreeModelRefCount *ref_model,
-                              gint                  ref_count)
-{
-  gtk_tree_model_ref_count_check_level (ref_model, NULL, ref_count,
-                                        FALSE, TRUE);
-}
-
-static inline void
-assert_level_referenced (GtkTreeModelRefCount *ref_model,
-                         gint                  ref_count,
-                         GtkTreeIter          *iter)
-{
-  gtk_tree_model_ref_count_check_level (ref_model, iter, ref_count,
-                                        FALSE, TRUE);
-}
-
-static inline void
-assert_node_ref_count (GtkTreeModelRefCount *ref_model,
-                       GtkTreeIter          *iter,
-                       gint                  ref_count)
-{
-  gtk_tree_model_ref_count_check_node (ref_model, iter, ref_count, TRUE);
-}
-
-
-#endif /* __GTK_TREE_MODEL_REF_COUNT_H__ */
diff --git a/gtk/tests/keyhash.c b/gtk/tests/keyhash.c
deleted file mode 100644 (file)
index 5bca1de..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/* keyhash.c
- * Copyright (C) 2012 Red Hat, Inc12 Red Hat, Inc
- * Authors: Matthias Clasen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "../../gtk/gtkkeyhash.h"
-#include "../../gtk/gtkprivate.h"
-
-static gint count;
-
-static void
-counting_destroy (gpointer data)
-{
-  count++;
-}
-
-static void
-test_basic (void)
-{
-  GtkKeyHash *hash;
-  GSList *keys;
-
-  count = 0;
-  hash = _gtk_key_hash_new (gdk_keymap_get_default (), counting_destroy);
-
-  keys = _gtk_key_hash_lookup (hash, 0, 0, 0, 0);
-  g_assert (keys == NULL);
-
-  _gtk_key_hash_add_entry (hash, 1, 0, NULL);
-  _gtk_key_hash_add_entry (hash, 1, 1, NULL);
-  _gtk_key_hash_add_entry (hash, 2, 0, NULL);
-  _gtk_key_hash_add_entry (hash, 3, 0, NULL);
-  _gtk_key_hash_add_entry (hash, 4, 0, NULL);
-
-  _gtk_key_hash_free (hash);
-
-  g_assert_cmpint (count, ==, 5);
-}
-
-
-#if 0
-typedef struct
-{
-  guint           keyval;
-  GdkModifierType modifiers;
-} Entry;
-
-static void
-test_lookup (GtkKeyHash      *hash,
-             guint            keyval,
-             GdkModifierType  modifiers,
-             GdkModifierType  mask,
-             gint             n_results,
-             ...)
-{
-  va_list ap;
-  gint d;
-  GSList *res, *l;
-  gint i;
-  GdkKeymapKey *keys;
-  gint n_keys;
-
-  gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (), keyval, &keys, &n_keys);
-  if (n_keys == 0)
-    return;
-
-  res = _gtk_key_hash_lookup (hash, keys[0].keycode, modifiers, mask, keys[0].group);
-  g_free (keys);
-
-  g_assert_cmpint (g_slist_length (res), ==, n_results);
-
-  va_start (ap, n_results);
-  for (i = 0, l = res; i < n_results; i++, l = l->next)
-    {
-      d = va_arg (ap, int);
-      g_assert_cmpint (d, ==, GPOINTER_TO_INT (l->data));
-    }
-  va_end (ap);
-
-  g_slist_free (res);
-}
-
-static void
-add_entries (GtkKeyHash *hash,
-             Entry      *entries)
-{
-  gint i;
-
-  for (i = 0; entries[i].keyval; i++)
-    _gtk_key_hash_add_entry (hash, entries[i].keyval, entries[i].modifiers, GINT_TO_POINTER (i+1));
-}
-
-#define DEFAULT_MASK (GDK_CONTROL_MASK \
-                      | GDK_SHIFT_MASK \
-                      | GDK_MOD1_MASK  \
-                      | GDK_SUPER_MASK \
-                      | GDK_HYPER_MASK \
-                      | GDK_META_MASK)
-
-static void
-test_match (void)
-{
-  GtkKeyHash *hash;
-  static Entry entries[] = {
-    { GDK_KEY_a, GDK_CONTROL_MASK },
-    { GDK_KEY_a, GDK_CONTROL_MASK|GDK_SHIFT_MASK } ,
-    { GDK_KEY_b, GDK_MOD1_MASK|GDK_CONTROL_MASK },
-    { GDK_KEY_F10, 0 },
-    {  0, 0 }
-  };
-
-  hash = _gtk_key_hash_new (gdk_keymap_get_default (), NULL);
-  add_entries (hash, entries);
-
-  test_lookup (hash, GDK_KEY_a, GDK_CONTROL_MASK, DEFAULT_MASK, 4, 1, 1, 2, 2);
-  test_lookup (hash, GDK_KEY_A, GDK_CONTROL_MASK, DEFAULT_MASK, 4, 1, 1, 2, 2);
-  test_lookup (hash, GDK_KEY_a, GDK_MOD1_MASK, DEFAULT_MASK, 0);
-  test_lookup (hash, GDK_KEY_F10, 0, DEFAULT_MASK, 4, 4, 4, 4, 4);
-  test_lookup (hash, GDK_KEY_F10, GDK_SHIFT_MASK, DEFAULT_MASK, 4, 4, 4, 4, 4);
-
-  _gtk_key_hash_free (hash);
-}
-
-static gboolean
-hyper_equals_super (void)
-{
-  GdkModifierType mods1, mods2;
-
-  mods1 = GDK_HYPER_MASK;
-  gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods1);
-  mods1 = mods1 & ~GDK_HYPER_MASK;
-  mods2 = GDK_SUPER_MASK;
-  gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods2);
-  mods2 = mods2 & ~GDK_SUPER_MASK;
-
-  return mods1 == mods2;
-}
-
-static void
-test_virtual (void)
-{
-  GtkKeyHash *hash;
-  static Entry entries[] = {
-    { GDK_KEY_a, GDK_SUPER_MASK },
-    { GDK_KEY_b, GDK_HYPER_MASK } ,
-    { GDK_KEY_c, GDK_META_MASK },
-    { GDK_KEY_d, GDK_SUPER_MASK|GDK_HYPER_MASK },
-    {  0, 0 }
-  };
-
-  hash = _gtk_key_hash_new (gdk_keymap_get_default (), NULL);
-  add_entries (hash, entries);
-
-  test_lookup (hash, GDK_KEY_a, GDK_SUPER_MASK, DEFAULT_MASK, 2, 1, 1);
-  test_lookup (hash, GDK_KEY_a, GDK_HYPER_MASK, DEFAULT_MASK, 0);
-  test_lookup (hash, GDK_KEY_b, GDK_HYPER_MASK, DEFAULT_MASK, 2, 2, 2);
-  test_lookup (hash, GDK_KEY_c, GDK_META_MASK,  DEFAULT_MASK, 2, 3, 3);
-  if (hyper_equals_super ())
-    {
-      GdkModifierType mods;
-
-      /* test that colocated virtual modifiers don't count twice */
-      test_lookup (hash, GDK_KEY_d, GDK_SUPER_MASK, DEFAULT_MASK, 0);
-      test_lookup (hash, GDK_KEY_d, GDK_HYPER_MASK, DEFAULT_MASK, 0);
-
-      mods = GDK_HYPER_MASK;
-      gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods);
-      test_lookup (hash, GDK_KEY_d, mods, DEFAULT_MASK, 0);
-    }
-
-  _gtk_key_hash_free (hash);
-}
-#endif
-
-int
-main (int argc, char **argv)
-{
-  /* initialize test program */
-  gtk_test_init (&argc, &argv);
-
-  g_test_add_func ("/keyhash/basic", test_basic);
-#if 0
-  /* FIXME: need to make these independent of xkb configuration */
-  g_test_add_func ("/keyhash/match", test_match);
-  g_test_add_func ("/keyhash/virtual", test_virtual);
-#endif
-  return g_test_run();
-}
diff --git a/gtk/tests/liststore.c b/gtk/tests/liststore.c
deleted file mode 100644 (file)
index 4455a13..0000000
+++ /dev/null
@@ -1,1139 +0,0 @@
-/* Extensive GtkListStore tests.
- * Copyright (C) 2007  Imendio AB
- * Authors: Kristian Rietveld  <kris@imendio.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* To do:
- *  - Test implementations of the interfaces: DnD, sortable, buildable
- *    and the tree model interface itself?
- *  - Need to check if the emitted signals are right.
- *  - Needs analysis with the code coverage tool once it is there.
- */
-
-#include <gtk/gtk.h>
-
-#include "treemodel.h"
-
-static inline gboolean
-iters_equal (GtkTreeIter *a,
-            GtkTreeIter *b)
-{
-  if (a->stamp != b->stamp)
-    return FALSE;
-
-  if (a->user_data != b->user_data)
-    return FALSE;
-
-  /* user_data2 and user_data3 are not used in GtkListStore */
-
-  return TRUE;
-}
-
-static gboolean
-iter_position (GtkListStore *store,
-              GtkTreeIter  *iter,
-              int           n)
-{
-  gboolean ret = TRUE;
-  GtkTreePath *path;
-
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
-  if (!path)
-    return FALSE;
-
-  if (gtk_tree_path_get_indices (path)[0] != n)
-    ret = FALSE;
-
-  gtk_tree_path_free (path);
-
-  return ret;
-}
-
-/*
- * Fixture
- */
-typedef struct
-{
-  GtkTreeIter iter[5];
-  GtkListStore *store;
-} ListStore;
-
-static void
-list_store_setup (ListStore     *fixture,
-                 gconstpointer  test_data)
-{
-  int i;
-
-  fixture->store = gtk_list_store_new (1, G_TYPE_INT);
-
-  for (i = 0; i < 5; i++)
-    {
-      gtk_list_store_insert (fixture->store, &fixture->iter[i], i);
-      gtk_list_store_set (fixture->store, &fixture->iter[i], 0, i, -1);
-    }
-}
-
-static void
-list_store_teardown (ListStore     *fixture,
-                    gconstpointer  test_data)
-{
-  g_object_unref (fixture->store);
-}
-
-/*
- * The actual tests.
- */
-
-static void
-check_model (ListStore *fixture,
-            gint      *new_order,
-            gint       skip)
-{
-  int i;
-  GtkTreePath *path;
-
-  path = gtk_tree_path_new ();
-  gtk_tree_path_down (path);
-
-  /* Check validity of the model and validity of the iters-persistent
-   * claim.
-   */
-  for (i = 0; i < 5; i++)
-    {
-      GtkTreeIter iter;
-
-      if (i == skip)
-       continue;
-
-      /* The saved iterator at new_order[i] should match the iterator
-       * at i.
-       */
-
-      gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
-                              &iter, path);
-
-      g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter));
-      g_assert (iters_equal (&iter, &fixture->iter[new_order[i]]));
-
-      gtk_tree_path_next (path);
-    }
-
-  gtk_tree_path_free (path);
-}
-
-/* insertion */
-static void
-list_store_test_insert_high_values (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  gtk_list_store_insert (store, &iter, 1234);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  gtk_list_store_insert (store, &iter2, 765);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-list_store_test_append (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  gtk_list_store_append (store, &iter);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  gtk_list_store_append (store, &iter2);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-list_store_test_prepend (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  gtk_list_store_prepend (store, &iter);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  gtk_list_store_prepend (store, &iter2);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-list_store_test_insert_after (void)
-{
-  GtkTreeIter iter, iter2, iter3;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  gtk_list_store_append (store, &iter);
-  gtk_list_store_append (store, &iter2);
-
-  gtk_list_store_insert_after (store, &iter3, &iter);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter3));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter3, 1));
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 1));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 2));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 2));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter3, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-list_store_test_insert_after_NULL (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  gtk_list_store_append (store, &iter);
-
-  /* move_after NULL is basically a prepend */
-  gtk_list_store_insert_after (store, &iter2, NULL);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
-  g_assert (iters_equal (&iter2, &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-list_store_test_insert_before (void)
-{
-  GtkTreeIter iter, iter2, iter3;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  gtk_list_store_append (store, &iter);
-  gtk_list_store_append (store, &iter2);
-
-  gtk_list_store_insert_before (store, &iter3, &iter2);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter3));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter3, 1));
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 1));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 2));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter3, &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 2));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter3, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-list_store_test_insert_before_NULL (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  gtk_list_store_append (store, &iter);
-
-  /* move_before NULL is basically an append */
-  gtk_list_store_insert_before (store, &iter2, NULL);
-  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-/* setting values */
-static void
-list_store_set_gvalue_to_transform (void)
-{
-  GtkListStore *store;
-  GtkTreeIter iter;
-  GValue value = G_VALUE_INIT;
-
-  /* https://bugzilla.gnome.org/show_bug.cgi?id=677649 */
-  store = gtk_list_store_new (1, G_TYPE_LONG);
-  gtk_list_store_append (store, &iter);
-
-  g_value_init (&value, G_TYPE_INT);
-  g_value_set_int (&value, 42);
-  gtk_list_store_set_value (store, &iter, 0, &value);
-}
-
-/* removal */
-static void
-list_store_test_remove_begin (ListStore     *fixture,
-                             gconstpointer  user_data)
-{
-  int new_order[5] = { -1, 1, 2, 3, 4 };
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  /* Remove node at 0 */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
-  gtk_tree_path_free (path);
-
-  g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
-  g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[0]));
-  g_assert (iters_equal (&iter, &fixture->iter[1]));
-
-  check_model (fixture, new_order, 0);
-}
-
-static void
-list_store_test_remove_middle (ListStore     *fixture,
-                              gconstpointer  user_data)
-{
-  int new_order[5] = { 0, 1, -1, 3, 4 };
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  /* Remove node at 2 */
-  path = gtk_tree_path_new_from_indices (2, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
-  gtk_tree_path_free (path);
-
-  g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
-  g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[2]));
-  g_assert (iters_equal (&iter, &fixture->iter[3]));
-
-  check_model (fixture, new_order, 2);
-}
-
-static void
-list_store_test_remove_end (ListStore     *fixture,
-                           gconstpointer  user_data)
-{
-  int new_order[5] = { 0, 1, 2, 3, -1 };
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  /* Remove node at 4 */
-  path = gtk_tree_path_new_from_indices (4, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
-  gtk_tree_path_free (path);
-
-  g_assert (gtk_list_store_remove (fixture->store, &iter) == FALSE);
-  g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[4]));
-
-  check_model (fixture, new_order, 4);
-}
-
-static void
-list_store_test_clear (ListStore     *fixture,
-                      gconstpointer  user_data)
-{
-  int i;
-
-  gtk_list_store_clear (fixture->store);
-
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL) == 0);
-
-  for (i = 0; i < 5; i++)
-    g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[i]));
-}
-
-/* reorder */
-
-static void
-list_store_test_reorder (ListStore     *fixture,
-                        gconstpointer  user_data)
-{
-  int new_order[5] = { 4, 1, 0, 2, 3 };
-
-  gtk_list_store_reorder (fixture->store, new_order);
-  check_model (fixture, new_order, -1);
-}
-
-/* swapping */
-
-static void
-list_store_test_swap_begin (ListStore     *fixture,
-                           gconstpointer  user_data)
-{
-  /* We swap nodes 0 and 1 at the beginning */
-  int new_order[5] = { 1, 0, 2, 3, 4 };
-
-  GtkTreeIter iter_a;
-  GtkTreeIter iter_b;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
-
-  gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_swap_middle_next (ListStore     *fixture,
-                                 gconstpointer  user_data)
-{
-  /* We swap nodes 2 and 3 in the middle that are next to each other */
-  int new_order[5] = { 0, 1, 3, 2, 4 };
-
-  GtkTreeIter iter_a;
-  GtkTreeIter iter_b;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "2"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
-
-  gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_swap_middle_apart (ListStore     *fixture,
-                                  gconstpointer  user_data)
-{
-  /* We swap nodes 1 and 3 in the middle that are apart from each other */
-  int new_order[5] = { 0, 3, 2, 1, 4 };
-
-  GtkTreeIter iter_a;
-  GtkTreeIter iter_b;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "1"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
-
-  gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_swap_end (ListStore     *fixture,
-                         gconstpointer  user_data)
-{
-  /* We swap nodes 3 and 4 at the end */
-  int new_order[5] = { 0, 1, 2, 4, 3 };
-
-  GtkTreeIter iter_a;
-  GtkTreeIter iter_b;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "3"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
-
-  gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_swap_single (void)
-{
-  GtkTreeIter iter;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  /* Check if swap on a store with a single node does not corrupt
-   * the store.
-   */
-
-  gtk_list_store_append (store, &iter);
-  iter_copy = iter;
-
-  gtk_list_store_swap (store, &iter, &iter);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  g_object_unref (store);
-}
-
-/* move after */
-
-static void
-list_store_test_move_after_from_start (ListStore     *fixture,
-                                      gconstpointer  user_data)
-{
-  /* We move node 0 after 2 */
-  int new_order[5] = { 1, 2, 0, 3, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
-
-  gtk_list_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_after_next (ListStore     *fixture,
-                                gconstpointer  user_data)
-{
-  /* We move node 2 after 3 */
-  int new_order[5] = { 0, 1, 3, 2, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
-
-  gtk_list_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_after_apart (ListStore     *fixture,
-                                 gconstpointer  user_data)
-{
-  /* We move node 1 after 3 */
-  int new_order[5] = { 0, 2, 3, 1, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
-
-  gtk_list_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_after_end (ListStore     *fixture,
-                               gconstpointer  user_data)
-{
-  /* We move node 2 after 4 */
-  int new_order[5] = { 0, 1, 3, 4, 2 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
-
-  gtk_list_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_after_from_end (ListStore     *fixture,
-                                    gconstpointer  user_data)
-{
-  /* We move node 4 after 1 */
-  int new_order[5] = { 0, 1, 4, 2, 3 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
-
-  gtk_list_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_after_change_ends (ListStore     *fixture,
-                                       gconstpointer  user_data)
-{
-  /* We move 0 after 4, this will cause both the head and tail ends to
-   * change.
-   */
-  int new_order[5] = { 1, 2, 3, 4, 0 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
-
-  gtk_list_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_after_NULL (ListStore     *fixture,
-                                gconstpointer  user_data)
-{
-  /* We move node 2, NULL should prepend */
-  int new_order[5] = { 2, 0, 1, 3, 4 };
-
-  GtkTreeIter iter;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-
-  gtk_list_store_move_after (fixture->store, &iter, NULL);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_after_single (void)
-{
-  GtkTreeIter iter;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  /* Check if move-after on a store with a single node does not corrupt
-   * the store.
-   */
-
-  gtk_list_store_append (store, &iter);
-  iter_copy = iter;
-
-  gtk_list_store_move_after (store, &iter, NULL);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  gtk_list_store_move_after (store, &iter, &iter);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  g_object_unref (store);
-}
-
-/* move before */
-
-static void
-list_store_test_move_before_next (ListStore     *fixture,
-                                 gconstpointer  user_data)
-{
-  /* We move node 3 before 2 */
-  int new_order[5] = { 0, 1, 3, 2, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
-
-  gtk_list_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_before_apart (ListStore     *fixture,
-                                  gconstpointer  user_data)
-{
-  /* We move node 1 before 3 */
-  int new_order[5] = { 0, 2, 1, 3, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
-
-  gtk_list_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_before_to_start (ListStore     *fixture,
-                                     gconstpointer  user_data)
-{
-  /* We move node 2 before 0 */
-  int new_order[5] = { 2, 0, 1, 3, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
-
-  gtk_list_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_before_from_end (ListStore     *fixture,
-                                     gconstpointer  user_data)
-{
-  /* We move node 4 before 2 (replace end) */
-  int new_order[5] = { 0, 1, 4, 2, 3 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
-
-  gtk_list_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_before_change_ends (ListStore     *fixture,
-                                        gconstpointer  user_data)
-{
-  /* We move node 4 before 0 */
-  int new_order[5] = { 4, 0, 1, 2, 3 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
-
-  gtk_list_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_before_NULL (ListStore     *fixture,
-                                 gconstpointer  user_data)
-{
-  /* We move node 2, NULL should append */
-  int new_order[5] = { 0, 1, 3, 4, 2 };
-
-  GtkTreeIter iter;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-
-  gtk_list_store_move_before (fixture->store, &iter, NULL);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-list_store_test_move_before_single (void)
-{
-  GtkTreeIter iter;
-  GtkTreeIter iter_copy;
-  GtkListStore *store;
-
-  store = gtk_list_store_new (1, G_TYPE_INT);
-
-  /* Check if move-before on a store with a single node does not corrupt
-   * the store.
-   */
-
-  gtk_list_store_append (store, &iter);
-  iter_copy = iter;
-
-  gtk_list_store_move_before (store, &iter, NULL);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  gtk_list_store_move_before (store, &iter, &iter);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  g_object_unref (store);
-}
-
-
-/* iter invalidation */
-
-static void
-list_store_test_iter_previous_invalid (ListStore     *fixture,
-                                       gconstpointer  user_data)
-{
-  GtkTreeIter iter;
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
-                                          &iter) == FALSE);
-  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
-  g_assert (iter.stamp == 0);
-}
-
-static void
-list_store_test_iter_next_invalid (ListStore     *fixture,
-                                   gconstpointer  user_data)
-{
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  path = gtk_tree_path_new_from_indices (4, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
-  gtk_tree_path_free (path);
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
-                                      &iter) == FALSE);
-  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
-  g_assert (iter.stamp == 0);
-}
-
-static void
-list_store_test_iter_children_invalid (ListStore     *fixture,
-                                       gconstpointer  user_data)
-{
-  GtkTreeIter iter, child;
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
-  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
-
-  g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
-                                          &child, &iter) == FALSE);
-  g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
-  g_assert (child.stamp == 0);
-}
-
-static void
-list_store_test_iter_nth_child_invalid (ListStore     *fixture,
-                                        gconstpointer  user_data)
-{
-  GtkTreeIter iter, child;
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
-  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
-                                           &child, &iter, 0) == FALSE);
-  g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
-  g_assert (child.stamp == 0);
-}
-
-static void
-list_store_test_iter_parent_invalid (ListStore     *fixture,
-                                     gconstpointer  user_data)
-{
-  GtkTreeIter iter, child;
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child);
-  g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == TRUE);
-
-  g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
-                                        &iter, &child) == FALSE);
-  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
-  g_assert (iter.stamp == 0);
-}
-
-
-/* main */
-
-void
-register_list_store_tests (void)
-{
-  /* insertion */
-  g_test_add_func ("/ListStore/insert-high-values",
-                  list_store_test_insert_high_values);
-  g_test_add_func ("/ListStore/append",
-                  list_store_test_append);
-  g_test_add_func ("/ListStore/prepend",
-                  list_store_test_prepend);
-  g_test_add_func ("/ListStore/insert-after",
-                  list_store_test_insert_after);
-  g_test_add_func ("/ListStore/insert-after-NULL",
-                  list_store_test_insert_after_NULL);
-  g_test_add_func ("/ListStore/insert-before",
-                  list_store_test_insert_before);
-  g_test_add_func ("/ListStore/insert-before-NULL",
-                  list_store_test_insert_before_NULL);
-
-  /* setting values (FIXME) */
-  g_test_add_func ("/ListStore/set-gvalue-to-transform",
-                   list_store_set_gvalue_to_transform);
-
-  /* removal */
-  g_test_add ("/ListStore/remove-begin", ListStore, NULL,
-             list_store_setup, list_store_test_remove_begin,
-             list_store_teardown);
-  g_test_add ("/ListStore/remove-middle", ListStore, NULL,
-             list_store_setup, list_store_test_remove_middle,
-             list_store_teardown);
-  g_test_add ("/ListStore/remove-end", ListStore, NULL,
-             list_store_setup, list_store_test_remove_end,
-             list_store_teardown);
-
-  g_test_add ("/ListStore/clear", ListStore, NULL,
-             list_store_setup, list_store_test_clear,
-             list_store_teardown);
-
-  /* reordering */
-  g_test_add ("/ListStore/reorder", ListStore, NULL,
-             list_store_setup, list_store_test_reorder,
-             list_store_teardown);
-
-  /* swapping */
-  g_test_add ("/ListStore/swap-begin", ListStore, NULL,
-             list_store_setup, list_store_test_swap_begin,
-             list_store_teardown);
-  g_test_add ("/ListStore/swap-middle-next", ListStore, NULL,
-             list_store_setup, list_store_test_swap_middle_next,
-             list_store_teardown);
-  g_test_add ("/ListStore/swap-middle-apart", ListStore, NULL,
-             list_store_setup, list_store_test_swap_middle_apart,
-             list_store_teardown);
-  g_test_add ("/ListStore/swap-end", ListStore, NULL,
-             list_store_setup, list_store_test_swap_end,
-             list_store_teardown);
-  g_test_add_func ("/ListStore/swap-single",
-                  list_store_test_swap_single);
-
-  /* moving */
-  g_test_add ("/ListStore/move-after-from-start", ListStore, NULL,
-             list_store_setup, list_store_test_move_after_from_start,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-after-next", ListStore, NULL,
-             list_store_setup, list_store_test_move_after_next,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-after-apart", ListStore, NULL,
-             list_store_setup, list_store_test_move_after_apart,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-after-end", ListStore, NULL,
-             list_store_setup, list_store_test_move_after_end,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-after-from-end", ListStore, NULL,
-             list_store_setup, list_store_test_move_after_from_end,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-after-change-ends", ListStore, NULL,
-             list_store_setup, list_store_test_move_after_change_ends,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-after-NULL", ListStore, NULL,
-             list_store_setup, list_store_test_move_after_NULL,
-             list_store_teardown);
-  g_test_add_func ("/ListStore/move-after-single",
-                  list_store_test_move_after_single);
-
-  g_test_add ("/ListStore/move-before-next", ListStore, NULL,
-             list_store_setup, list_store_test_move_before_next,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-before-apart", ListStore, NULL,
-             list_store_setup, list_store_test_move_before_apart,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-before-to-start", ListStore, NULL,
-             list_store_setup, list_store_test_move_before_to_start,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-before-from-end", ListStore, NULL,
-             list_store_setup, list_store_test_move_before_from_end,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-before-change-ends", ListStore, NULL,
-             list_store_setup, list_store_test_move_before_change_ends,
-             list_store_teardown);
-  g_test_add ("/ListStore/move-before-NULL", ListStore, NULL,
-             list_store_setup, list_store_test_move_before_NULL,
-             list_store_teardown);
-  g_test_add_func ("/ListStore/move-before-single",
-                  list_store_test_move_before_single);
-
-  /* iter invalidation */
-  g_test_add ("/ListStore/iter-prev-invalid", ListStore, NULL,
-              list_store_setup, list_store_test_iter_previous_invalid,
-              list_store_teardown);
-  g_test_add ("/ListStore/iter-next-invalid", ListStore, NULL,
-              list_store_setup, list_store_test_iter_next_invalid,
-              list_store_teardown);
-  g_test_add ("/ListStore/iter-children-invalid", ListStore, NULL,
-              list_store_setup, list_store_test_iter_children_invalid,
-              list_store_teardown);
-  g_test_add ("/ListStore/iter-nth-child-invalid", ListStore, NULL,
-              list_store_setup, list_store_test_iter_nth_child_invalid,
-              list_store_teardown);
-  g_test_add ("/ListStore/iter-parent-invalid", ListStore, NULL,
-              list_store_setup, list_store_test_iter_parent_invalid,
-              list_store_teardown);
-}
diff --git a/gtk/tests/modelrefcount.c b/gtk/tests/modelrefcount.c
deleted file mode 100644 (file)
index 2d39d9c..0000000
+++ /dev/null
@@ -1,976 +0,0 @@
-/* GtkTreeModel ref counting tests
- * Copyright (C) 2011  Kristian Rietveld  <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "gtktreemodelrefcount.h"
-#include "treemodel.h"
-
-/* And the tests themselves */
-
-static void
-test_list_no_reference (void)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-
-  assert_root_level_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_list_reference_during_creation (void)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_root_level_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_list_reference_after_creation (void)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  assert_root_level_unreferenced (ref_model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_root_level_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_list_reference_reordered (void)
-{
-  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  assert_root_level_unreferenced (ref_model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter3, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter4, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter5, NULL);
-
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  gtk_tree_store_move_after (GTK_TREE_STORE (model),
-                             &iter1, &iter5);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  gtk_tree_store_move_after (GTK_TREE_STORE (model),
-                             &iter3, &iter4);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_root_level_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-
-static void
-test_tree_no_reference (void)
-{
-  GtkTreeIter iter, child;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_tree_reference_during_creation (void)
-{
-  GtkTreeIter iter, child;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_not_entire_model_referenced (ref_model, 1);
-  assert_level_unreferenced (ref_model, &child);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_tree_reference_after_creation (void)
-{
-  GtkTreeIter iter, child;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_not_entire_model_referenced (ref_model, 1);
-  assert_level_unreferenced (ref_model, &child);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_tree_reference_reordered (void)
-{
-  GtkTreeIter parent;
-  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  assert_root_level_unreferenced (ref_model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, &parent);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, &parent);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter3, &parent);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter4, &parent);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter5, &parent);
-
-  tree_view = gtk_tree_view_new_with_model (model);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  gtk_tree_store_move_after (GTK_TREE_STORE (model),
-                             &iter1, &iter5);
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  gtk_tree_store_move_after (GTK_TREE_STORE (model),
-                             &iter3, &iter4);
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_tree_reference_expand_all (void)
-{
-  GtkTreeIter iter, child;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_not_entire_model_referenced (ref_model, 1);
-  assert_level_unreferenced (ref_model, &child);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_not_entire_model_referenced (ref_model, 1);
-  assert_level_unreferenced (ref_model, &child);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_tree_reference_collapse_all (void)
-{
-  GtkTreeIter iter, child;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  tree_view = gtk_tree_view_new_with_model (model);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_not_entire_model_referenced (ref_model, 1);
-  assert_level_unreferenced (ref_model, &child);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_tree_reference_expand_collapse (void)
-{
-  GtkTreeIter parent1, parent2, child;
-  GtkTreePath *path1, *path2;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent2);
-
-  path1 = gtk_tree_model_get_path (model, &parent1);
-  path2 = gtk_tree_model_get_path (model, &parent2);
-
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_unreferenced (ref_model, &parent2);
-
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path1, FALSE);
-
-  assert_level_referenced (ref_model, 1, &parent1);
-  assert_level_unreferenced (ref_model, &parent2);
-
-  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path1);
-
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_unreferenced (ref_model, &parent2);
-
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path2, FALSE);
-
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_referenced (ref_model, 1, &parent2);
-
-  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path2);
-
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_unreferenced (ref_model, &parent2);
-
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path2, FALSE);
-
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_referenced (ref_model, 1, &parent2);
-
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path1, FALSE);
-
-  assert_level_referenced (ref_model, 1, &parent1);
-  assert_level_referenced (ref_model, 1, &parent2);
-
-  gtk_tree_path_free (path1);
-  gtk_tree_path_free (path2);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (ref_model);
-}
-
-static void
-test_row_reference_list (void)
-{
-  GtkTreeIter iter0, iter1, iter2;
-  GtkTreePath *path;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeRowReference *row_ref;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
-
-  assert_root_level_unreferenced (ref_model);
-
-  /* create and remove a row ref and check reference counts */
-  path = gtk_tree_path_new_from_indices (1, -1);
-  row_ref = gtk_tree_row_reference_new (model, path);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &iter2, 0);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_root_level_unreferenced (ref_model);
-
-  /* the same, but then also with a tree view monitoring the model */
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  row_ref = gtk_tree_row_reference_new (model, path);
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &iter1, 2);
-  assert_node_ref_count (ref_model, &iter2, 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &iter2, 0);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_root_level_unreferenced (ref_model);
-
-  gtk_tree_path_free (path);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_row_reference_list_remove (void)
-{
-  GtkTreeIter iter0, iter1, iter2;
-  GtkTreePath *path;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeRowReference *row_ref;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
-
-  assert_root_level_unreferenced (ref_model);
-
-  /* test creating the row reference and then removing the node */
-  path = gtk_tree_path_new_from_indices (1, -1);
-  row_ref = gtk_tree_row_reference_new (model, path);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &iter2, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter1);
-
-  assert_root_level_unreferenced (ref_model);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_root_level_unreferenced (ref_model);
-
-  /* test creating a row ref, removing another node and then removing
-   * the row ref node.
-   */
-  row_ref = gtk_tree_row_reference_new (model, path);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &iter2, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter0);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
-
-  g_assert (!gtk_tree_model_get_iter_first (model, &iter0));
-
-  gtk_tree_row_reference_free (row_ref);
-
-  gtk_tree_path_free (path);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_row_reference_tree (void)
-{
-  GtkTreeIter iter0, iter1, iter2;
-  GtkTreeIter child0, child1, child2;
-  GtkTreeIter grandchild0, grandchild1, grandchild2;
-  GtkTreePath *path;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeRowReference *row_ref, *row_ref1;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  /* create and remove a row ref and check reference counts */
-  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
-  row_ref = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &grandchild1, 1);
-  assert_node_ref_count (ref_model, &iter2, 0);
-  assert_node_ref_count (ref_model, &child2, 0);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  /* again, with path 1:1 */
-  path = gtk_tree_path_new_from_indices (1, 0, -1);
-  row_ref = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &grandchild1, 0);
-  assert_node_ref_count (ref_model, &iter2, 0);
-  assert_node_ref_count (ref_model, &child2, 0);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  /* both row refs existent at once and also with a tree view monitoring
-   * the model
-   */
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
-  row_ref = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 2);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &grandchild1, 1);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &child2, 0);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  path = gtk_tree_path_new_from_indices (1, 0, -1);
-  row_ref1 = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 3);
-  assert_node_ref_count (ref_model, &child1, 2);
-  assert_node_ref_count (ref_model, &grandchild1, 1);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &child2, 0);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 2);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &grandchild1, 0);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &child2, 0);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &grandchild1, 0);
-  assert_node_ref_count (ref_model, &iter2, 0);
-  assert_node_ref_count (ref_model, &child2, 0);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_tree_row_reference_free (row_ref1);
-
-  assert_root_level_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_row_reference_tree_remove (void)
-{
-  GtkTreeIter iter0, iter1, iter2;
-  GtkTreeIter child0, child1, child2;
-  GtkTreeIter grandchild0, grandchild1, grandchild2;
-  GtkTreePath *path;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeRowReference *row_ref, *row_ref1, *row_ref2;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
-  row_ref = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (2, 0, -1);
-  row_ref1 = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (2, -1);
-  row_ref2 = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &grandchild1, 1);
-  assert_node_ref_count (ref_model, &iter2, 2);
-  assert_node_ref_count (ref_model, &child2, 1);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandchild1);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 0);
-  assert_node_ref_count (ref_model, &child1, 0);
-  assert_node_ref_count (ref_model, &iter2, 2);
-  assert_node_ref_count (ref_model, &child2, 1);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 0);
-  assert_node_ref_count (ref_model, &child1, 0);
-  assert_node_ref_count (ref_model, &iter2, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  gtk_tree_row_reference_free (row_ref);
-  gtk_tree_row_reference_free (row_ref1);
-  gtk_tree_row_reference_free (row_ref2);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_row_reference_tree_remove_ancestor (void)
-{
-  GtkTreeIter iter0, iter1, iter2;
-  GtkTreeIter child0, child1, child2;
-  GtkTreeIter grandchild0, grandchild1, grandchild2;
-  GtkTreePath *path;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeRowReference *row_ref, *row_ref1;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
-  row_ref = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (2, 0, -1);
-  row_ref1 = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &grandchild1, 1);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &child2, 1);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &child1);
-
-  assert_node_ref_count (ref_model, &iter0, 0);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 0);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &child2, 1);
-  assert_node_ref_count (ref_model, &grandchild2, 0);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  gtk_tree_row_reference_free (row_ref);
-  gtk_tree_row_reference_free (row_ref1);
-
-  g_object_unref (ref_model);
-}
-
-static void
-test_row_reference_tree_expand (void)
-{
-  GtkTreeIter iter0, iter1, iter2;
-  GtkTreeIter child0, child1, child2;
-  GtkTreeIter grandchild0, grandchild1, grandchild2;
-  GtkTreePath *path;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeRowReference *row_ref, *row_ref1, *row_ref2;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-  tree_view = gtk_tree_view_new_with_model (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
-
-  assert_root_level_referenced (ref_model, 1);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
-  row_ref = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (2, 0, -1);
-  row_ref1 = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  path = gtk_tree_path_new_from_indices (2, -1);
-  row_ref2 = gtk_tree_row_reference_new (model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &child0, 1);
-  assert_node_ref_count (ref_model, &grandchild0, 1);
-  assert_node_ref_count (ref_model, &iter1, 2);
-  assert_node_ref_count (ref_model, &child1, 2);
-  assert_node_ref_count (ref_model, &grandchild1, 2);
-  assert_node_ref_count (ref_model, &iter2, 3);
-  assert_node_ref_count (ref_model, &child2, 2);
-  assert_node_ref_count (ref_model, &grandchild2, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandchild1);
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &child0, 1);
-  assert_node_ref_count (ref_model, &grandchild0, 1);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &iter2, 3);
-  assert_node_ref_count (ref_model, &child2, 2);
-  assert_node_ref_count (ref_model, &grandchild2, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &child0, 1);
-  assert_node_ref_count (ref_model, &grandchild0, 1);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 1);
-  assert_node_ref_count (ref_model, &iter2, 2);
-
-  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 0);
-  assert_node_ref_count (ref_model, &iter2, 2);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
-
-  assert_node_ref_count (ref_model, &iter0, 1);
-  assert_node_ref_count (ref_model, &child0, 0);
-  assert_node_ref_count (ref_model, &grandchild0, 0);
-  assert_node_ref_count (ref_model, &iter1, 1);
-  assert_node_ref_count (ref_model, &child1, 0);
-
-  gtk_tree_row_reference_free (row_ref);
-  gtk_tree_row_reference_free (row_ref1);
-  gtk_tree_row_reference_free (row_ref2);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (ref_model);
-}
-
-void
-register_model_ref_count_tests (void)
-{
-  /* lists (though based on GtkTreeStore) */
-  g_test_add_func ("/TreeModel/ref-count/list/no-reference",
-                   test_list_no_reference);
-  g_test_add_func ("/TreeModel/ref-count/list/reference-during-creation",
-                   test_list_reference_during_creation);
-  g_test_add_func ("/TreeModel/ref-count/list/reference-after-creation",
-                   test_list_reference_after_creation);
-  g_test_add_func ("/TreeModel/ref-count/list/reference-reordered",
-                   test_list_reference_reordered);
-
-  /* trees */
-  g_test_add_func ("/TreeModel/ref-count/tree/no-reference",
-                   test_tree_no_reference);
-  g_test_add_func ("/TreeModel/ref-count/tree/reference-during-creation",
-                   test_tree_reference_during_creation);
-  g_test_add_func ("/TreeModel/ref-count/tree/reference-after-creation",
-                   test_tree_reference_after_creation);
-  g_test_add_func ("/TreeModel/ref-count/tree/expand-all",
-                   test_tree_reference_expand_all);
-  g_test_add_func ("/TreeModel/ref-count/tree/collapse-all",
-                   test_tree_reference_collapse_all);
-  g_test_add_func ("/TreeModel/ref-count/tree/expand-collapse",
-                   test_tree_reference_expand_collapse);
-  g_test_add_func ("/TreeModel/ref-count/tree/reference-reordered",
-                   test_tree_reference_reordered);
-
-  /* row references */
-  g_test_add_func ("/TreeModel/ref-count/row-reference/list",
-                   test_row_reference_list);
-  g_test_add_func ("/TreeModel/ref-count/row-reference/list-remove",
-                   test_row_reference_list_remove);
-  g_test_add_func ("/TreeModel/ref-count/row-reference/tree",
-                   test_row_reference_tree);
-  g_test_add_func ("/TreeModel/ref-count/row-reference/tree-remove",
-                   test_row_reference_tree_remove);
-  g_test_add_func ("/TreeModel/ref-count/row-reference/tree-remove-ancestor",
-                   test_row_reference_tree_remove_ancestor);
-  g_test_add_func ("/TreeModel/ref-count/row-reference/tree-expand",
-                   test_row_reference_tree_expand);
-}
diff --git a/gtk/tests/object.c b/gtk/tests/object.c
deleted file mode 100644 (file)
index 1e06ded..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/* Gtk+ object tests
- * Copyright (C) 2007 Imendio AB
- * Authors: Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <gtk/gtk.h>
-#include <string.h>
-
-/* --- helper macros for property value generation --- */
-/* dvalue=+0: generate minimum value
- * dvalue=.x: generate value within value range proportional to x.
- * dvalue=+1: generate maximum value
- * dvalue=-1: generate random value within value range
- * dvalue=+2: initialize value from default_value
- */
-#define ASSIGN_VALUE(__g_value_set_func, __value, PSPECTYPE, __pspec, __default_value, __minimum, __maximum, __dvalue) do { \
-  PSPECTYPE __p = (PSPECTYPE) __pspec; \
-  __g_value_set_func (__value, SELECT_VALUE (__dvalue, __p->__default_value, __p->__minimum, __p->__maximum)); \
-} while (0)
-#define SELECT_VALUE(__dvalue, __default_value, __minimum, __maximum) ( \
-  __dvalue >= 0 && __dvalue <= 1 ? __minimum * (1 - __dvalue) + __dvalue * __maximum : \
-    __dvalue <= -1 ? g_test_rand_double_range (__minimum, __maximum) : \
-      __default_value)
-#define SELECT_NAME(__dvalue) ( \
-  __dvalue == 0 ? "minimum" : \
-    __dvalue == 1 ? "maximum" : \
-      __dvalue >= +2 ? "default" : \
-        __dvalue == 0.5 ? "medium" : \
-          __dvalue > 0 && __dvalue < 1 ? "fractional" : \
-            "random")
-#define MATCH_ANY_VALUE         ((void*) 0xf1874c23)
-
-/* --- property blacklists --- */
-typedef struct {
-  const char   *type_name;
-  const char   *name;
-  gconstpointer value;
-} IgnoreProperty;
-static const IgnoreProperty*
-list_ignore_properties (gboolean buglist)
-{
-  /* currently untestable properties */
-  static const IgnoreProperty ignore_properties[] = {
-    { "GtkContainer",           "child",                NULL, },                        /* needs working child widget */
-    { "GtkRadioMenuItem",       "group",                NULL, },                        /* needs working sibling */
-    { "GtkWidget",              "parent",               NULL, },                        /* needs working parent widget */
-    { "GtkCList",               "selection-mode",       (void*) GTK_SELECTION_NONE, },
-    { "GtkWidget",              "has-default",          (void*) TRUE, },                /* conflicts with toplevel-less widgets */
-    { "GtkWidget",              "screen",               NULL, },
-    { "GtkWindow",              "type-hint",            (void*) GDK_WINDOW_TYPE_HINT_DND, }, /* conflicts with ::visible=TRUE */
-    { "GtkCellView",            "background",           (void*) "", },                  /* "" is not a valid background color */
-    { "GtkColorButton",         "color",                (void*) NULL, },                /* not a valid boxed color */
-    { "GtkInputDialog",         "has-separator",        (void*) MATCH_ANY_VALUE, },     /* property disabled */
-    { "GtkMessageDialog",       "has-separator",        (void*) MATCH_ANY_VALUE, },     /* property disabled */
-    { "GtkFontSelectionDialog", "has-separator",        (void*) MATCH_ANY_VALUE, },     /* property disabled */
-    { "GtkColorSelectionDialog","has-separator",        (void*) MATCH_ANY_VALUE, },     /* property disabled */
-    { "GtkColorSelection",      "child",                NULL, },
-    { "GtkColorSelection",      "current-color",        (void*) NULL, },                /* not a valid boxed color */
-    { "GtkComboBox",            "row-span-column",      (void*) MATCH_ANY_VALUE },      /* GtkComboBoxEntry needs a tree model for this */
-    { "GtkComboBox",            "column-span-column",   (void*) MATCH_ANY_VALUE },      /* GtkComboBoxEntry needs a tree model for this */
-    { "GtkFileChooserButton",   "select-multiple",      (void*) MATCH_ANY_VALUE },      /* property disabled */
-    { "GtkFileChooserButton",   "action",               (void*) GTK_FILE_CHOOSER_ACTION_SAVE },
-    { "GtkFileChooserButton",   "action",               (void*) GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER },
-    { "GtkFileChooserWidget",   "select-multiple",      (void*) 0x1 },                  /* property conflicts */
-    { "GtkFileChooserDialog",   "select-multiple",      (void*) MATCH_ANY_VALUE },      /* property disabled */
-    { "GtkMenu",                "accel-path",           (void*) MATCH_ANY_VALUE },      /* has odd restrictions in the setter */
-    { "GtkMenuItem",            "accel-path",           (void*) MATCH_ANY_VALUE },      /* has odd restrictions in the setter */
-    { "GtkRecentChooserMenu",   "select-multiple",      (void*) MATCH_ANY_VALUE },      /* property disabled */
-    { "GtkTextView",            "overwrite",            (void*) MATCH_ANY_VALUE },      /* needs text buffer */
-    { "GtkToolbar",             "icon-size",            (void*) GTK_ICON_SIZE_INVALID },
-    { NULL, NULL, NULL }
-  };
-  /* properties suspected to be Gdk/Gtk+ bugs */
-  static const IgnoreProperty bug_properties[] = {
-    { "GtkComboBox",            "active",               (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL model bug */
-    { "GtkCTree",               "spacing",              (void*) MATCH_ANY_VALUE },      /* FIXME: triggers signedness bug */
-    { "GtkFileChooserButton",   "local-only",           (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL path assertion */
-    { "GtkFileChooserDialog",   "local-only",           (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL path assertion */
-    { "GtkFileChooserWidget",   "local-only",           (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL path assertion */
-    { "GtkMenu",                "tearoff-state",        (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL widget cast */
-    { "GtkText",                "text-position",        (void*) MATCH_ANY_VALUE },      /* FIXME: segfaults, fix property minimum/maximum */
-    { NULL, NULL, NULL }
-  };
-  if (buglist)
-    return bug_properties;
-  else
-    return ignore_properties;
-}
-
-/* --- test functions --- */
-static void
-pspec_select_value (GParamSpec *pspec,
-                    GValue     *value,
-                    double      dvalue)
-{
-  /* generate a value suitable for pspec */
-  if (G_IS_PARAM_SPEC_CHAR (pspec))
-    ASSIGN_VALUE (g_value_set_char, value, GParamSpecChar*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_UCHAR (pspec))
-    ASSIGN_VALUE (g_value_set_uchar, value, GParamSpecUChar*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_INT (pspec))
-    ASSIGN_VALUE (g_value_set_int, value, GParamSpecInt*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_UINT (pspec))
-    ASSIGN_VALUE (g_value_set_uint, value, GParamSpecUInt*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_LONG (pspec))
-    ASSIGN_VALUE (g_value_set_long, value, GParamSpecLong*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_ULONG (pspec))
-    ASSIGN_VALUE (g_value_set_ulong, value, GParamSpecULong*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_INT64 (pspec))
-    ASSIGN_VALUE (g_value_set_int64, value, GParamSpecInt64*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_UINT64 (pspec))
-    ASSIGN_VALUE (g_value_set_uint64, value, GParamSpecUInt64*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_FLOAT (pspec))
-    ASSIGN_VALUE (g_value_set_float, value, GParamSpecFloat*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
-    ASSIGN_VALUE (g_value_set_double, value, GParamSpecDouble*, pspec, default_value, minimum, maximum, dvalue);
-  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
-    g_value_set_boolean (value, SELECT_VALUE (dvalue, ((GParamSpecBoolean*) pspec)->default_value, FALSE, TRUE));
-  else if (G_IS_PARAM_SPEC_UNICHAR (pspec))
-    g_value_set_uint (value, SELECT_VALUE (dvalue, ((GParamSpecUnichar*) pspec)->default_value, FALSE, TRUE));
-  else if (G_IS_PARAM_SPEC_GTYPE (pspec))
-    g_value_set_gtype (value, SELECT_VALUE ((int) dvalue, ((GParamSpecGType*) pspec)->is_a_type, 0, GTK_TYPE_WIDGET));
-  else if (G_IS_PARAM_SPEC_STRING (pspec))
-    {
-      GParamSpecString *sspec = (GParamSpecString*) pspec;
-      if (dvalue >= +2)
-        g_value_set_string (value, sspec->default_value);
-      if (dvalue > 0 && sspec->cset_first && sspec->cset_nth)
-        g_value_take_string (value, g_strdup_printf ("%c%c", sspec->cset_first[0], sspec->cset_nth[0]));
-      else /* if (sspec->ensure_non_null) */
-        g_value_set_string (value, "");
-    }
-  else if (G_IS_PARAM_SPEC_ENUM (pspec))
-    {
-      GParamSpecEnum *espec = (GParamSpecEnum*) pspec;
-      if (dvalue >= +2)
-        g_value_set_enum (value, espec->default_value);
-      if (dvalue >= 0 && dvalue <= 1)
-        g_value_set_enum (value, espec->enum_class->values[(int) ((espec->enum_class->n_values - 1) * dvalue)].value);
-      else if (dvalue <= -1)
-        g_value_set_enum (value, espec->enum_class->values[g_test_rand_int_range (0, espec->enum_class->n_values)].value);
-    }
-  else if (G_IS_PARAM_SPEC_FLAGS (pspec))
-    {
-      GParamSpecFlags *fspec = (GParamSpecFlags*) pspec;
-      if (dvalue >= +2)
-        g_value_set_flags (value, fspec->default_value);
-      if (dvalue >= 0 && dvalue <= 1)
-        g_value_set_flags (value, fspec->flags_class->values[(int) ((fspec->flags_class->n_values - 1) * dvalue)].value);
-      else if (dvalue <= -1)
-        g_value_set_flags (value, fspec->flags_class->values[g_test_rand_int_range (0, fspec->flags_class->n_values)].value);
-    }
-  /* unimplemented:
-   * G_IS_PARAM_SPEC_PARAM
-   * G_IS_PARAM_SPEC_BOXED
-   * G_IS_PARAM_SPEC_POINTER
-   * G_IS_PARAM_SPEC_VALUE_ARRAY
-   * G_IS_PARAM_SPEC_OBJECT
-   */
-}
-
-static gpointer
-value_as_pointer (GValue *value)
-{
-  if (g_value_fits_pointer (value))
-    return g_value_peek_pointer (value);
-  if (G_VALUE_HOLDS_BOOLEAN (value))
-    return GINT_TO_POINTER(g_value_get_boolean (value));
-  if (G_VALUE_HOLDS_CHAR (value))
-    return (void*) (gssize) g_value_get_char (value);
-  if (G_VALUE_HOLDS_UCHAR (value))
-    return (void*) (gsize) g_value_get_uchar (value);
-  if (G_VALUE_HOLDS_INT (value))
-    return GINT_TO_POINTER(g_value_get_int (value));
-  if (G_VALUE_HOLDS_UINT (value))
-    return GUINT_TO_POINTER(g_value_get_uint (value));
-  if (G_VALUE_HOLDS_LONG (value))
-    return (void*) g_value_get_long (value);
-  if (G_VALUE_HOLDS_ULONG (value))
-    return (void*) g_value_get_ulong (value);
-  if (G_VALUE_HOLDS_FLOAT (value))
-    return (void*) (gssize) g_value_get_float (value);
-  if (G_VALUE_HOLDS_DOUBLE (value))
-    return (void*) (gssize) g_value_get_double (value);
-  if (G_VALUE_HOLDS_ENUM (value))
-    return (void*) (gssize) g_value_get_enum (value);
-  if (G_VALUE_HOLDS_FLAGS (value))
-    return (void*) (gsize) g_value_get_flags (value);
-  return (void*) 0x1373babe;
-}
-
-static void
-object_test_property (GObject           *object,
-                      GParamSpec        *pspec,
-                      double             dvalue)
-{
-  /* test setting of a normal writable property */
-  if (pspec->flags & G_PARAM_WRITABLE &&
-      !(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
-    {
-      GValue value = G_VALUE_INIT;
-      guint i;
-      const IgnoreProperty *ignore_properties;
-      /* select value to set */
-      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-      pspec_select_value (pspec, &value, dvalue);
-      /* ignore untestable properties */
-      ignore_properties = list_ignore_properties (FALSE);
-      for (i = 0; ignore_properties[i].name; i++)
-        if (g_strcmp0 ("", ignore_properties[i].name) ||
-            (g_type_is_a (G_OBJECT_TYPE (object), g_type_from_name (ignore_properties[i].type_name)) &&
-             strcmp (pspec->name, ignore_properties[i].name) == 0 &&
-             (MATCH_ANY_VALUE == ignore_properties[i].value ||
-              value_as_pointer (&value) == ignore_properties[i].value ||
-              (G_VALUE_HOLDS_STRING (&value) &&
-               strcmp (g_value_get_string (&value), ignore_properties[i].value) == 0))))
-          break;
-      /* ignore known property bugs if not testing thoroughly */
-      if (ignore_properties[i].name == NULL && !g_test_thorough ())
-        {
-          ignore_properties = list_ignore_properties (TRUE);
-          for (i = 0; ignore_properties[i].name; i++)
-            if (g_type_is_a (G_OBJECT_TYPE (object), g_type_from_name (ignore_properties[i].type_name)) &&
-                strcmp (pspec->name, ignore_properties[i].name) == 0 &&
-                (MATCH_ANY_VALUE == ignore_properties[i].value ||
-                 value_as_pointer (&value) == ignore_properties[i].value ||
-                 (G_VALUE_HOLDS_STRING (&value) &&
-                  strcmp (g_value_get_string (&value), ignore_properties[i].value) == 0)))
-              break;
-        }
-      /* assign unignored properties */
-      if (ignore_properties[i].name == NULL)
-        {
-          if (g_test_verbose ())
-            g_print ("PropertyTest: %s::%s := (%s value (%s): %p)\n",
-                     g_type_name (G_OBJECT_TYPE (object)), pspec->name,
-                     SELECT_NAME (dvalue), g_type_name (G_VALUE_TYPE (&value)),
-                     value_as_pointer (&value));
-          g_object_set_property (object, pspec->name, &value);
-        }
-      /* cleanups */
-      g_value_unset (&value);
-    }
-}
-
-static void
-widget_test_properties (GtkWidget   *widget,
-                        double       dvalue)
-{
-  /* try setting all possible properties, according to dvalue */
-  guint i, n_pspecs = 0;
-  GParamSpec **pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (widget), &n_pspecs);
-  for (i = 0; i < n_pspecs; i++)
-    {
-      GParamSpec *pspec = pspecs[i];
-      if (pspec->flags & G_PARAM_WRITABLE &&
-          !(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
-        object_test_property (G_OBJECT (widget), pspecs[i], dvalue);
-    }
-  g_free (pspecs);
-}
-
-static void
-widget_fixups (GtkWidget *widget)
-{
-  /* post-constructor for widgets that need additional settings to work correctly */
-  if (GTK_IS_COMBO_BOX (widget))
-    {
-      GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
-      g_object_set (widget, "model", store, NULL);
-      g_object_unref (store);
-      gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "test text");
-    }
-}
-
-static void
-widget_property_tests (gconstpointer test_data)
-{
-  GType wtype = (GType) test_data;
-  /* create widget */
-  GtkWidget *widget = gtk_widget_new (wtype, NULL);
-  g_object_ref_sink (widget);
-  widget_fixups (widget);
-  /* test property values */
-  widget_test_properties (widget,  +2); /* test default_value */
-  widget_test_properties (widget,   0); /* test minimum */
-  widget_test_properties (widget, 0.5); /* test medium */
-  widget_test_properties (widget,   1); /* test maximum */
-  widget_test_properties (widget,  -1); /* test random value */
-  /* cleanup */
-  gtk_widget_destroy (widget);
-  g_object_unref (widget);
-}
-
-/* --- main test program --- */
-int
-main (int   argc,
-      char *argv[])
-{
-  const GType *otypes;
-  guint i;
-  /* initialize test program */
-  gtk_test_init (&argc, &argv);
-  gtk_test_register_all_types ();
-  /* install a property test for each widget type */
-  otypes = gtk_test_list_all_types (NULL);
-  for (i = 0; otypes[i]; i++)
-    if (g_type_is_a (otypes[i], GTK_TYPE_WIDGET) &&
-        G_TYPE_IS_OBJECT (otypes[i]) &&
-        !G_TYPE_IS_ABSTRACT (otypes[i]))
-      {
-        gchar *testpath = g_strdup_printf ("/properties/%s", g_type_name (otypes[i]));
-        g_test_add_data_func (testpath, (void*) otypes[i], widget_property_tests);
-        g_free (testpath);
-      }
-  return g_test_run ();
-}
diff --git a/gtk/tests/objects-finalize.c b/gtk/tests/objects-finalize.c
deleted file mode 100644 (file)
index 0e1eae0..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* objects-finalize.c
- * Copyright (C) 2013 Openismus GmbH
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Tristan Van Berkom <tristanvb@openismus.com>
- */
-#include <gtk/gtk.h>
-#include <string.h>
-
-#ifdef GDK_WINDOWING_X11
-# include <gdk/gdkx.h>
-#endif
-
-
-typedef GType (*GTypeGetFunc) (void);
-
-static gboolean finalized = FALSE;
-
-static gboolean
-main_loop_quit_cb (gpointer data)
-{
-  gtk_main_quit ();
-
-  g_assert (finalized);
-  return FALSE;
-}
-
-static void
-check_finalized (gpointer data,
-                GObject *where_the_object_was)
-{
-  gboolean *did_finalize = (gboolean *)data;
-
-  *did_finalize = TRUE;
-}
-
-static void
-test_finalize_object (gconstpointer data)
-{
-  GType test_type = GPOINTER_TO_SIZE (data);
-  GObject *object;
-
-  object = g_object_new (test_type, NULL);
-  g_assert (G_IS_OBJECT (object));
-
-  /* Make sure we have the only reference */
-  if (g_object_is_floating (object))
-    g_object_ref_sink (object);
-
-  /* Assert that the object finalizes properly */
-  g_object_weak_ref (object, check_finalized, &finalized);
-
-  /* Toplevels are owned by GTK+, just tell GTK+ to destroy it */
-  if (GTK_IS_WINDOW (object) || GTK_IS_INVISIBLE (object))
-    gtk_widget_destroy (GTK_WIDGET (object));
-  else
-    g_object_unref (object);
-
-  /* Even if the object did finalize, it may have left some dangerous stuff in the GMainContext */
-  g_timeout_add (50, main_loop_quit_cb, NULL);
-  gtk_main();
-}
-
-int
-main (int argc, char **argv)
-{
-  const GType *all_types;
-  guint n_types = 0, i;
-
-  /* initialize test program */
-  gtk_test_init (&argc, &argv);
-  gtk_test_register_all_types ();
-
-  all_types = gtk_test_list_all_types (&n_types);
-
-  for (i = 0; i < n_types; i++)
-    {
-      if (g_type_is_a (all_types[i], G_TYPE_OBJECT) &&
-         G_TYPE_IS_INSTANTIATABLE (all_types[i]) &&
-         !G_TYPE_IS_ABSTRACT (all_types[i]) &&
-#ifdef GDK_WINDOWING_X11
-         all_types[i] != GDK_TYPE_X11_WINDOW &&
-         all_types[i] != GDK_TYPE_X11_CURSOR &&
-         all_types[i] != GDK_TYPE_X11_SCREEN &&
-         all_types[i] != GDK_TYPE_X11_DISPLAY &&
-         all_types[i] != GDK_TYPE_X11_DEVICE_MANAGER_XI2 &&
-         all_types[i] != GDK_TYPE_X11_DISPLAY_MANAGER &&
-#endif
-         /* Not allowed to finalize a GdkPixbufLoader without calling gdk_pixbuf_loader_close() */
-         all_types[i] != GDK_TYPE_PIXBUF_LOADER &&
-         all_types[i] != gdk_pixbuf_simple_anim_iter_get_type())
-       {
-         gchar *test_path = g_strdup_printf ("/FinalizeObject/%s", g_type_name (all_types[i]));
-
-         g_test_add_data_func (test_path, GSIZE_TO_POINTER (all_types[i]), test_finalize_object);
-
-         g_free (test_path);
-       }
-    }
-
-  return g_test_run();
-}
diff --git a/gtk/tests/papersize.c b/gtk/tests/papersize.c
deleted file mode 100644 (file)
index 6af7acc..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2011 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-static void
-test_parse (void)
-{
-  GtkPaperSize *p;
-
-  p = gtk_paper_size_new (GTK_PAPER_NAME_A4);
-  g_assert (p != NULL);
-  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
-  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
-  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_a4");
-  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "A4");
-  g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "A4");
-  g_assert (!gtk_paper_size_is_custom (p));
-  gtk_paper_size_free (p);
-
-  p = gtk_paper_size_new (GTK_PAPER_NAME_B5);
-  g_assert (p != NULL);
-  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 176);
-  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 250);
-  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_b5");
-  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "B5");
-  g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "ISOB5");
-  g_assert (!gtk_paper_size_is_custom (p));
-  gtk_paper_size_free (p);
-
-  p = gtk_paper_size_new (GTK_PAPER_NAME_EXECUTIVE);
-  g_assert (p != NULL);
-  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 184);
-  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 266);
-  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "na_executive");
-  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "Executive");
-  g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "Executive");
-  g_assert (!gtk_paper_size_is_custom (p));
-  gtk_paper_size_free (p);
-
-  p = gtk_paper_size_new ("iso_a4_210x297mm");
-  g_assert (p != NULL);
-  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
-  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
-  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_a4");
-  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "A4");
-  g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "A4");
-  g_assert (!gtk_paper_size_is_custom (p));
-  gtk_paper_size_free (p);
-
-  p = gtk_paper_size_new ("custom_w1_20x30in");
-  g_assert (p != NULL);
-  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_INCH), ==, 20);
-  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_INCH), ==, 30);
-  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "custom_w1");
-  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "custom_w1");
-  g_assert (gtk_paper_size_is_custom (p));
-  gtk_paper_size_free (p);
-}
-
-static void
-test_compare (void)
-{
-  GtkPaperSize *a1, *a2, *b, *c;
-
-  a1 = gtk_paper_size_new (GTK_PAPER_NAME_A4);
-  a2 = gtk_paper_size_new ("iso_a4_210x297mm");
-  b = gtk_paper_size_new (GTK_PAPER_NAME_B5);
-  c = gtk_paper_size_new ("custom_w1_20x30in");
-
-  g_assert (gtk_paper_size_is_equal (a1, a2));
-  g_assert (!gtk_paper_size_is_equal (a1, b));
-  g_assert (!gtk_paper_size_is_equal (a1, c));
-  g_assert (!gtk_paper_size_is_equal (b, c));
-
-  gtk_paper_size_free (a1);
-  gtk_paper_size_free (a2);
-  gtk_paper_size_free (b);
-  gtk_paper_size_free (c);
-}
-
-static void
-test_units (void)
-{
-  GtkPaperSize *p;
-
-  p = gtk_paper_size_new (GTK_PAPER_NAME_A4);
-
-  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
-  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
-
-  /* compare up to 2 decimals */
-  g_assert_cmpint (100 * gtk_paper_size_get_width (p, GTK_UNIT_INCH), ==, 100 * 8.26);
-  g_assert_cmpint (100 * gtk_paper_size_get_height (p, GTK_UNIT_INCH), ==, 100 * 11.69);
-
-  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_POINTS), ==, 595);
-  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_POINTS), ==, 841);
-
-  gtk_paper_size_free (p);
-}
-
-int
-main (int argc, char *argv[])
-{
-  gtk_test_init (&argc, &argv);
-
-  g_test_add_func ("/paper-size/parse", test_parse);
-  g_test_add_func ("/paper-size/compare", test_compare);
-  g_test_add_func ("/paper-size/units", test_units);
-
-  return g_test_run();
-}
diff --git a/gtk/tests/rbtree.c b/gtk/tests/rbtree.c
deleted file mode 100644 (file)
index d73d862..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-/* GtkRBTree tests.
- *
- * Copyright (C) 2011, Red Hat, Inc.
- * Authors: Benjamin Otte <otte@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <locale.h>
-
-#include "../../gtk/gtkrbtree.h"
-
-/* _gtk_rbtree_test */
-
-static guint
-get_total_count (GtkRBNode *node)
-{
-  guint child_total = 0;
-
-  child_total += (guint) node->left->total_count;
-  child_total += (guint) node->right->total_count;
-
-  if (node->children)
-    child_total += (guint) node->children->root->total_count;
-
-  return child_total + 1;
-}
-
-static guint
-count_total (GtkRBTree *tree,
-             GtkRBNode *node)
-{
-  guint res;
-  
-  if (_gtk_rbtree_is_nil (node))
-    return 0;
-  
-  res =
-    count_total (tree, node->left) +
-    count_total (tree, node->right) +
-    (guint)1 +
-    (node->children ? count_total (node->children, node->children->root) : 0);
-
-  if (res != node->total_count)
-    g_print ("total count incorrect for node\n");
-
-  if (get_total_count (node) != node->total_count)
-    g_error ("Node has incorrect total count %u, should be %u", node->total_count, get_total_count (node));
-  
-  return res;
-}
-
-static gint
-_count_nodes (GtkRBTree *tree,
-              GtkRBNode *node)
-{
-  gint res;
-  if (_gtk_rbtree_is_nil (node))
-    return 0;
-
-  g_assert (node->left);
-  g_assert (node->right);
-
-  res = (_count_nodes (tree, node->left) +
-         _count_nodes (tree, node->right) + 1);
-
-  if (res != node->count)
-    g_print ("Tree failed\n");
-  return res;
-}
-
-static void
-_gtk_rbtree_test_height (GtkRBTree *tree,
-                         GtkRBNode *node)
-{
-  gint computed_offset = 0;
-
-  /* This whole test is sort of a useless truism. */
-  
-  if (!_gtk_rbtree_is_nil (node->left))
-    computed_offset += node->left->offset;
-
-  if (!_gtk_rbtree_is_nil (node->right))
-    computed_offset += node->right->offset;
-
-  if (node->children && !_gtk_rbtree_is_nil (node->children->root))
-    computed_offset += node->children->root->offset;
-
-  if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset)
-    g_error ("node has broken offset\n");
-
-  if (!_gtk_rbtree_is_nil (node->left))
-    _gtk_rbtree_test_height (tree, node->left);
-
-  if (!_gtk_rbtree_is_nil (node->right))
-    _gtk_rbtree_test_height (tree, node->right);
-
-  if (node->children && !_gtk_rbtree_is_nil (node->children->root))
-    _gtk_rbtree_test_height (node->children, node->children->root);
-}
-
-static void
-_gtk_rbtree_test_dirty (GtkRBTree *tree,
-                       GtkRBNode *node,
-                        gint      expected_dirtyness)
-{
-
-  if (expected_dirtyness)
-    {
-      g_assert (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
-               GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
-               GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID) ||
-               GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID) ||
-               (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)));
-    }
-  else
-    {
-      g_assert (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) &&
-               ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID));
-      if (!_gtk_rbtree_is_nil (node->left))
-       g_assert (! GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
-      if (!_gtk_rbtree_is_nil (node->right))
-       g_assert (! GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
-      if (node->children != NULL)
-       g_assert (! GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
-    }
-
-  if (!_gtk_rbtree_is_nil (node->left))
-    _gtk_rbtree_test_dirty (tree, node->left, GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
-  if (!_gtk_rbtree_is_nil (node->right))
-    _gtk_rbtree_test_dirty (tree, node->right, GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
-  if (node->children != NULL && !_gtk_rbtree_is_nil (node->children->root))
-    _gtk_rbtree_test_dirty (node->children, node->children->root, GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
-}
-
-static void _gtk_rbtree_test_structure (GtkRBTree *tree);
-
-static guint
-_gtk_rbtree_test_structure_helper (GtkRBTree *tree,
-                                  GtkRBNode *node)
-{
-  guint left_blacks, right_blacks;
-
-  g_assert (!_gtk_rbtree_is_nil (node));
-
-  g_assert (node->left != NULL);
-  g_assert (node->right != NULL);
-  g_assert (node->parent != NULL);
-
-  if (!_gtk_rbtree_is_nil (node->left))
-    {
-      g_assert (node->left->parent == node);
-      left_blacks = _gtk_rbtree_test_structure_helper (tree, node->left);
-    }
-  else
-    left_blacks = 0;
-
-  if (!_gtk_rbtree_is_nil (node->right))
-    {
-      g_assert (node->right->parent == node);
-      right_blacks = _gtk_rbtree_test_structure_helper (tree, node->right);
-    }
-  else
-    right_blacks = 0;
-
-  if (node->children != NULL)
-    {
-      g_assert (node->children->parent_tree == tree);
-      g_assert (node->children->parent_node == node);
-
-      _gtk_rbtree_test_structure (node->children);
-    }
-
-  g_assert (left_blacks == right_blacks);
-
-  return left_blacks + (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK ? 1 : 0);
-}
-
-static void
-_gtk_rbtree_test_structure (GtkRBTree *tree)
-{
-  g_assert (tree->root);
-  if (_gtk_rbtree_is_nil (tree->root))
-    return;
-
-  g_assert (_gtk_rbtree_is_nil (tree->root->parent));
-  _gtk_rbtree_test_structure_helper (tree, tree->root);
-}
-
-static void
-_gtk_rbtree_test (GtkRBTree *tree)
-{
-  GtkRBTree *tmp_tree;
-
-  if (tree == NULL)
-    return;
-
-  /* Test the entire tree */
-  tmp_tree = tree;
-  while (tmp_tree->parent_tree)
-    tmp_tree = tmp_tree->parent_tree;
-  
-  if (_gtk_rbtree_is_nil (tmp_tree->root))
-    return;
-
-  _gtk_rbtree_test_structure (tmp_tree);
-
-  g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) +
-            _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count);
-      
-  _gtk_rbtree_test_height (tmp_tree, tmp_tree->root);
-  _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID));
-  g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count);
-}
-
-/* gtk_rbtree_print() - unused, for debugging only */
-
-static void
-gtk_rbtree_print_node (GtkRBTree *tree,
-                       GtkRBNode *node,
-                       gint       depth)
-{
-  gint i;
-  for (i = 0; i < depth; i++)
-    g_print ("\t");
-
-  g_print ("(%p - %s) (Offset %d) (Parity %d) (Validity %d%d%d)\n",
-          node,
-          (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ",
-          node->offset,
-          node->total_count,
-          (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))?1:0,
-          (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))?1:0,
-          (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))?1:0);
-  if (node->children != NULL)
-    {
-      g_print ("Looking at child.\n");
-      gtk_rbtree_print_node (node->children, node->children->root, depth + 1);
-      g_print ("Done looking at child.\n");
-    }
-  if (!_gtk_rbtree_is_nil (node->left))
-    {
-      gtk_rbtree_print_node (tree, node->left, depth+1);
-    }
-  if (!_gtk_rbtree_is_nil (node->right))
-    {
-      gtk_rbtree_print_node (tree, node->right, depth+1);
-    }
-}
-
-/* not static so the debugger finds it. */
-void gtk_rbtree_print (GtkRBTree *tree);
-
-void
-gtk_rbtree_print (GtkRBTree *tree)
-{
-  g_return_if_fail (tree != NULL);
-
-  if (_gtk_rbtree_is_nil (tree->root))
-    g_print ("Empty tree...\n");
-  else
-    gtk_rbtree_print_node (tree, tree->root, 0);
-}
-
-/* actual tests */
-
-static guint
-append_elements (GtkRBTree *tree,
-                 guint      depth,
-                 guint      elements_per_depth,
-                 gboolean   check,
-                 guint      height)
-{
-  GtkRBNode *node;
-  guint i;
-
-  g_assert (depth > 0);
-
-  node = NULL;
-  depth--;
-
-  for (i = 0; i < elements_per_depth; i++)
-    {
-      node = _gtk_rbtree_insert_after (tree, node, ++height, TRUE);
-      if (depth)
-        {
-          node->children = _gtk_rbtree_new ();
-          node->children->parent_tree = tree;
-          node->children->parent_node = node;
-          height = append_elements (node->children, depth, elements_per_depth, check, height);
-        }
-      if (check)
-        _gtk_rbtree_test (tree);
-    }
-
-  return height;
-}
-
-static GtkRBTree *
-create_rbtree (guint depth,
-               guint elements_per_depth,
-               gboolean check)
-{
-  GtkRBTree *tree;
-
-  tree = _gtk_rbtree_new ();
-
-  append_elements (tree, depth, elements_per_depth, check, 0);
-
-  _gtk_rbtree_test (tree);
-
-  return tree;
-}
-
-static void
-test_create (void)
-{
-  GtkRBTree *tree;
-
-  tree = create_rbtree (5, 5, TRUE);
-
-  _gtk_rbtree_free (tree);
-}
-
-static void
-test_insert_after (void)
-{
-  guint i;
-  GtkRBTree *tree;
-  GtkRBNode *node;
-
-  tree = _gtk_rbtree_new ();
-  node = NULL;
-
-  for (i = 1; i <= 100; i++)
-    {
-      node = _gtk_rbtree_insert_after (tree, node, i, TRUE);
-      _gtk_rbtree_test (tree);
-      g_assert (tree->root->count == i);
-      g_assert (tree->root->total_count == i);
-      g_assert (tree->root->offset == i * (i + 1) / 2);
-    }
-
-  _gtk_rbtree_free (tree);
-}
-
-static void
-test_insert_before (void)
-{
-  guint i;
-  GtkRBTree *tree;
-  GtkRBNode *node;
-
-  tree = _gtk_rbtree_new ();
-  node = NULL;
-
-  for (i = 1; i <= 100; i++)
-    {
-      node = _gtk_rbtree_insert_before (tree, node, i, TRUE);
-      _gtk_rbtree_test (tree);
-      g_assert (tree->root->count == i);
-      g_assert (tree->root->total_count == i);
-      g_assert (tree->root->offset == i * (i + 1) / 2);
-    }
-
-  _gtk_rbtree_free (tree);
-}
-
-static void
-test_remove_node (void)
-{
-  GtkRBTree *tree;
-
-  tree = create_rbtree (3, 16, g_test_thorough ());
-
-  while (tree->root->count > 1)
-    {
-      GtkRBTree *find_tree;
-      GtkRBNode *find_node;
-      guint i;
-      
-      i = g_test_rand_int_range (0, tree->root->total_count);
-      if (!_gtk_rbtree_find_index (tree, i, &find_tree, &find_node))
-        {
-          /* We search an available index, so we mustn't fail. */
-          g_assert_not_reached ();
-        }
-      
-      _gtk_rbtree_test (find_tree);
-
-      if (find_tree->root->count == 1)
-        {
-          _gtk_rbtree_remove (find_tree);
-        }
-      else
-        _gtk_rbtree_remove_node (find_tree, find_node);
-      _gtk_rbtree_test (tree);
-    }
-
-  _gtk_rbtree_free (tree);
-}
-
-static void
-test_remove_root (void)
-{
-  GtkRBTree *tree;
-  GtkRBNode *node;
-
-  tree = _gtk_rbtree_new ();
-  
-  node = _gtk_rbtree_insert_after (tree, NULL, 1, TRUE);
-  _gtk_rbtree_insert_after (tree, node, 2, TRUE);
-  _gtk_rbtree_insert_before (tree, node, 3, TRUE);
-
-  _gtk_rbtree_remove_node (tree, node);
-
-  _gtk_rbtree_free (tree);
-}
-
-static gint *
-fisher_yates_shuffle (guint n_items)
-{
-  gint *list;
-  guint i, j;
-
-  list = g_new (gint, n_items);
-
-  for (i = 0; i < n_items; i++)
-    {
-      j = g_random_int_range (0, i + 1);
-      list[i] = list[j];
-      list[j] = i;
-    }
-
-  return list;
-}
-
-static GtkRBTree *
-create_unsorted_tree (gint  *order,
-                      guint  n)
-{
-  GtkRBTree *tree;
-  GtkRBNode *node;
-  guint i;
-
-  tree = _gtk_rbtree_new ();
-  node = NULL;
-
-  for (i = 0; i < n; i++)
-    {
-      node = _gtk_rbtree_insert_after (tree, node, 0, TRUE);
-    }
-
-  for (i = 0; i < n; i++)
-    {
-      node = _gtk_rbtree_find_count (tree, order[i] + 1);
-      _gtk_rbtree_node_set_height (tree, node, i);
-    }
-
-  _gtk_rbtree_test (tree);
-
-  return tree;
-}
-
-static void
-test_reorder (void)
-{
-  guint n = g_test_perf () ? 1000000 : 100;
-  GtkRBTree *tree;
-  GtkRBNode *node;
-  gint *reorder;
-  guint i;
-  double elapsed;
-
-  reorder = fisher_yates_shuffle (n);
-  tree = create_unsorted_tree (reorder, n);
-
-  g_test_timer_start ();
-
-  _gtk_rbtree_reorder (tree, reorder, n);
-
-  elapsed = g_test_timer_elapsed ();
-  if (g_test_perf ())
-    g_test_minimized_result (elapsed, "reordering rbtree with %u items: %gsec", n, elapsed);
-
-  _gtk_rbtree_test (tree);
-
-  for (node = _gtk_rbtree_first (tree), i = 0;
-       node != NULL;
-       node = _gtk_rbtree_next (tree, node), i++)
-    {
-      g_assert (GTK_RBNODE_GET_HEIGHT (node) == i);
-    }
-  g_assert (i == n);
-
-  _gtk_rbtree_free (tree);
-}
-
-int
-main (int argc, char *argv[])
-{
-  g_test_init (&argc, &argv, NULL);
-  setlocale (LC_ALL, "C");
-  g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
-
-  g_test_add_func ("/rbtree/create", test_create);
-  g_test_add_func ("/rbtree/insert_after", test_insert_after);
-  g_test_add_func ("/rbtree/insert_before", test_insert_before);
-  g_test_add_func ("/rbtree/remove_node", test_remove_node);
-  g_test_add_func ("/rbtree/remove_root", test_remove_root);
-  g_test_add_func ("/rbtree/reorder", test_reorder);
-
-  return g_test_run ();
-}
diff --git a/gtk/tests/recentmanager.c b/gtk/tests/recentmanager.c
deleted file mode 100644 (file)
index 84b7c67..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/* GTK - The GIMP Toolkit
- * gtkrecentmanager.c: a manager for the recently used resources
- *
- * Copyright (C) 2006 Emmanuele Bassi
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <glib/gstdio.h>
-#include <gtk/gtk.h>
-
-const gchar *uri = "file:///tmp/testrecentchooser.txt";
-const gchar *uri2 = "file:///tmp/testrecentchooser2.txt";
-
-static void
-recent_manager_get_default (void)
-{
-  GtkRecentManager *manager;
-  GtkRecentManager *manager2;
-
-  manager = gtk_recent_manager_get_default ();
-  g_assert (manager != NULL);
-
-  manager2 = gtk_recent_manager_get_default ();
-  g_assert (manager == manager2);
-}
-
-static void
-recent_manager_add (void)
-{
-  GtkRecentManager *manager;
-  GtkRecentData *recent_data;
-  gboolean res;
-
-  manager = gtk_recent_manager_get_default ();
-
-  recent_data = g_slice_new0 (GtkRecentData);
-
-  /* mime type is mandatory */
-  recent_data->mime_type = NULL;
-  recent_data->app_name = "testrecentchooser";
-  recent_data->app_exec = "testrecentchooser %u";
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      res = gtk_recent_manager_add_full (manager,
-                                         uri,
-                                         recent_data);
-    }
-  g_test_trap_assert_failed ();
-
-  /* app name is mandatory */
-  recent_data->mime_type = "text/plain";
-  recent_data->app_name = NULL;
-  recent_data->app_exec = "testrecentchooser %u";
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      res = gtk_recent_manager_add_full (manager,
-                                         uri,
-                                         recent_data);
-    }
-  g_test_trap_assert_failed ();
-
-  /* app exec is mandatory */
-  recent_data->mime_type = "text/plain";
-  recent_data->app_name = "testrecentchooser";
-  recent_data->app_exec = NULL;
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      res = gtk_recent_manager_add_full (manager,
-                                         uri,
-                                         recent_data);
-    }
-  g_test_trap_assert_failed ();
-
-  recent_data->mime_type = "text/plain";
-  recent_data->app_name = "testrecentchooser";
-  recent_data->app_exec = "testrecentchooser %u";
-  res = gtk_recent_manager_add_full (manager,
-                                     uri,
-                                     recent_data);
-  g_assert (res == TRUE);
-
-  g_slice_free (GtkRecentData, recent_data);
-}
-
-typedef struct {
-  GMainLoop *main_loop;
-  gint counter;
-} AddManyClosure;
-
-static void
-check_bulk (GtkRecentManager *manager,
-            gpointer          data)
-{
-  AddManyClosure *closure = data;
-
-  if (g_test_verbose ())
-    g_print (G_STRLOC ": counter = %d\n", closure->counter);
-
-  g_assert_cmpint (closure->counter, ==, 100);
-
-  if (g_main_loop_is_running (closure->main_loop))
-    g_main_loop_quit (closure->main_loop);
-}
-
-static void
-recent_manager_add_many (void)
-{
-  GtkRecentManager *manager = g_object_new (GTK_TYPE_RECENT_MANAGER,
-                                            "filename", "recently-used.xbel",
-                                            NULL);
-  AddManyClosure *closure = g_new (AddManyClosure, 1);
-  GtkRecentData *data = g_slice_new0 (GtkRecentData);
-  gint i;
-
-  closure->main_loop = g_main_loop_new (NULL, FALSE);
-  closure->counter = 0;
-
-  g_signal_connect (manager, "changed", G_CALLBACK (check_bulk), closure);
-
-  for (i = 0; i < 100; i++)
-    {
-      gchar *new_uri;
-
-      data->mime_type = "text/plain";
-      data->app_name = "testrecentchooser";
-      data->app_exec = "testrecentchooser %u";
-
-      if (g_test_verbose ())
-        g_print (G_STRLOC ": adding item %d\n", i);
-
-      new_uri = g_strdup_printf ("file:///doesnotexist-%d.txt", i);
-      gtk_recent_manager_add_full (manager, new_uri, data);
-      g_free (new_uri);
-
-      closure->counter += 1;
-    }
-
-  g_main_loop_run (closure->main_loop);
-
-  g_main_loop_unref (closure->main_loop);
-  g_slice_free (GtkRecentData, data);
-  g_free (closure);
-  g_object_unref (manager);
-
-  g_assert_cmpint (g_unlink ("recently-used.xbel"), ==, 0);
-}
-
-static void
-recent_manager_has_item (void)
-{
-  GtkRecentManager *manager;
-  gboolean res;
-
-  manager = gtk_recent_manager_get_default ();
-
-  res = gtk_recent_manager_has_item (manager, "file:///tmp/testrecentdoesnotexist.txt");
-  g_assert (res == FALSE);
-
-  res = gtk_recent_manager_has_item (manager, uri);
-  g_assert (res == TRUE);
-}
-
-static void
-recent_manager_move_item (void)
-{
-  GtkRecentManager *manager;
-  gboolean res;
-  GError *error;
-
-  manager = gtk_recent_manager_get_default ();
-
-  error = NULL;
-  res = gtk_recent_manager_move_item (manager,
-                                      "file:///tmp/testrecentdoesnotexist.txt",
-                                      uri2,
-                                      &error);
-  g_assert (res == FALSE);
-  g_assert (error != NULL);
-  g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
-  g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
-  g_error_free (error);
-
-  error = NULL;
-  res = gtk_recent_manager_move_item (manager, uri, uri2, &error);
-  g_assert (res == TRUE);
-  g_assert (error == NULL);
-
-  res = gtk_recent_manager_has_item (manager, uri);
-  g_assert (res == FALSE);
-
-  res = gtk_recent_manager_has_item (manager, uri2);
-  g_assert (res == TRUE);
-}
-
-static void
-recent_manager_lookup_item (void)
-{
-  GtkRecentManager *manager;
-  GtkRecentInfo *info;
-  GError *error;
-
-  manager = gtk_recent_manager_get_default ();
-
-  error = NULL;
-  info = gtk_recent_manager_lookup_item (manager,
-                                         "file:///tmp/testrecentdoesnotexist.txt",
-                                         &error);
-  g_assert (info == NULL);
-  g_assert (error != NULL);
-  g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
-  g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
-  g_error_free (error);
-
-  error = NULL;
-  info = gtk_recent_manager_lookup_item (manager, uri2, &error);
-  g_assert (info != NULL);
-  g_assert (error == NULL);
-
-  g_assert (gtk_recent_info_has_application (info, "testrecentchooser"));
-
-  gtk_recent_info_unref (info);
-}
-
-static void
-recent_manager_remove_item (void)
-{
-  GtkRecentManager *manager;
-  gboolean res;
-  GError *error;
-
-  manager = gtk_recent_manager_get_default ();
-
-  error = NULL;
-  res = gtk_recent_manager_remove_item (manager,
-                                        "file:///tmp/testrecentdoesnotexist.txt",
-                                        &error);
-  g_assert (res == FALSE);
-  g_assert (error != NULL);
-  g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
-  g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
-  g_error_free (error);
-
-  /* remove an item that's actually there */
-  error = NULL;
-  res = gtk_recent_manager_remove_item (manager, uri2, &error);
-  g_assert (res == TRUE);
-  g_assert (error == NULL);
-
-  res = gtk_recent_manager_has_item (manager, uri2);
-  g_assert (res == FALSE);
-}
-
-static void
-recent_manager_purge (void)
-{
-  GtkRecentManager *manager;
-  GtkRecentData *recent_data;
-  gint n;
-  GError *error;
-
-  manager = gtk_recent_manager_get_default ();
-
-  /* purge, add 1, purge again and check that 1 item has been purged */
-  error = NULL;
-  n = gtk_recent_manager_purge_items (manager, &error);
-  g_assert (error == NULL);
-
-  recent_data = g_slice_new0 (GtkRecentData);
-  recent_data->mime_type = "text/plain";
-  recent_data->app_name = "testrecentchooser";
-  recent_data->app_exec = "testrecentchooser %u";
-  gtk_recent_manager_add_full (manager, uri, recent_data);
-  g_slice_free (GtkRecentData, recent_data);
-
-  error = NULL;
-  n = gtk_recent_manager_purge_items (manager, &error);
-  g_assert (error == NULL);
-  g_assert (n == 1);
-}
-
-int
-main (int    argc,
-      char **argv)
-{
-  gtk_test_init (&argc, &argv, NULL);
-
-  g_test_add_func ("/recent-manager/get-default", recent_manager_get_default);
-  g_test_add_func ("/recent-manager/add", recent_manager_add);
-  g_test_add_func ("/recent-manager/add-many", recent_manager_add_many);
-  g_test_add_func ("/recent-manager/has-item", recent_manager_has_item);
-  g_test_add_func ("/recent-manager/move-item", recent_manager_move_item);
-  g_test_add_func ("/recent-manager/lookup-item", recent_manager_lookup_item);
-  g_test_add_func ("/recent-manager/remove-item", recent_manager_remove_item);
-  g_test_add_func ("/recent-manager/purge", recent_manager_purge);
-
-  return g_test_run ();
-}
diff --git a/gtk/tests/regression-tests.c b/gtk/tests/regression-tests.c
deleted file mode 100644 (file)
index e44eaa6..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Regression tests
- *
- * Copyright (C) 2011, Red Hat, Inc.
- * Authors: Benjamin Otte <otte@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-static void
-test_9d6da33ff5c5e41e3521e1afd63d2d67bc915753 (void)
-{
-  GtkWidget *window, *label;
-
-  window = gtk_window_new (GTK_WINDOW_POPUP);
-  label = gtk_label_new ("I am sensitive.");
-  gtk_container_add (GTK_CONTAINER (window), label);
-
-  gtk_widget_set_sensitive (label, FALSE);
-  gtk_widget_set_sensitive (window, FALSE);
-  gtk_widget_set_sensitive (label, TRUE);
-  gtk_widget_set_sensitive (window, TRUE);
-
-  g_assert (gtk_widget_get_sensitive (label));
-
-  gtk_widget_destroy (window);
-}
-
-static void
-test_94f00eb04dd1433cf1cc9a3341f485124e38abd1 (void)
-{
-  GtkWidget *window, *label;
-
-  window = gtk_window_new (GTK_WINDOW_POPUP);
-  label = gtk_label_new ("I am insensitive.");
-  gtk_container_add (GTK_CONTAINER (window), label);
-
-  gtk_widget_set_sensitive (window, FALSE);
-  gtk_widget_set_sensitive (label, FALSE);
-  gtk_widget_set_sensitive (label, TRUE);
-
-  g_assert (!gtk_widget_is_sensitive (label));
-
-  gtk_widget_destroy (window);
-}
-
-int
-main (int argc, char *argv[])
-{
-  gtk_test_init (&argc, &argv, NULL);
-
-  g_test_add_func ("/regression/94f00eb04dd1433cf1cc9a3341f485124e38abd1", test_94f00eb04dd1433cf1cc9a3341f485124e38abd1);
-  g_test_add_func ("/regression/9d6da33ff5c5e41e3521e1afd63d2d67bc915753", test_9d6da33ff5c5e41e3521e1afd63d2d67bc915753);
-
-  return g_test_run ();
-}
diff --git a/gtk/tests/sortmodel.c b/gtk/tests/sortmodel.c
deleted file mode 100644 (file)
index a24f8a3..0000000
+++ /dev/null
@@ -1,1243 +0,0 @@
-/* Extensive GtkTreeModelSort tests.
- * Copyright (C) 2009,2011  Kristian Rietveld  <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-#include "treemodel.h"
-#include "gtktreemodelrefcount.h"
-
-
-static void
-ref_count_single_level (void)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
-
-  assert_root_level_unreferenced (ref_model);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (sort_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_two_levels (void)
-{
-  GtkTreeIter parent1, parent2, iter;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_node_ref_count (ref_model, &iter, 0);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter, 1);
-
-  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter, 0);
-
-  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_node_ref_count (ref_model, &iter, 0);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (sort_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_three_levels (void)
-{
-  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
-  GtkTreeIter iter_parent1, iter_parent2;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   *   + parent1
-   *     + iter_parent1
-   *   + parent2
-   *     + iter_parent2
-   *     + iter_parent2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_unreferenced (ref_model, &parent2);
-
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 0);
-
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_path_append_index (path, 1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_path_up (path);
-  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (sort_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_delete_row (void)
-{
-  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
-  GtkTreeIter iter_parent1, iter_parent2;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkTreePath *path;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   *   + parent1
-   *     + iter_parent1
-   *   + parent2
-   *     + iter_parent2
-   *     + iter_parent2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  assert_root_level_referenced (ref_model, 1);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 0);
-  assert_level_unreferenced (ref_model, &parent1);
-  assert_level_unreferenced (ref_model, &parent2);
-
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 1);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter_parent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 2);
-  assert_level_referenced (ref_model, 1, &parent1);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_level_referenced (ref_model, 1, &parent2);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_level_referenced (ref_model, 1, &parent2);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-
-  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-
-  gtk_widget_destroy (tree_view);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (sort_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_cleanup (void)
-{
-  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
-  GtkTreeIter iter_parent1, iter_parent2;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   *   + parent1
-   *     + iter_parent1
-   *   + parent2
-   *     + iter_parent2
-   *     + iter_parent2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  gtk_widget_destroy (tree_view);
-
-  assert_node_ref_count (ref_model, &grandparent1, 0);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &parent1, 1);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (sort_model);
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_row_ref (void)
-{
-  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
-  GtkTreeIter iter_parent1, iter_parent2;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-  GtkTreePath *path;
-  GtkTreeRowReference *row_ref;
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  /* + grandparent1
-   * + grandparent2
-   *   + parent1
-   *     + iter_parent1
-   *   + parent2
-   *     + iter_parent2
-   *     + iter_parent2
-   */
-
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
-  row_ref = gtk_tree_row_reference_new (sort_model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  /* Referenced because the node is visible, its child level is built
-   * and referenced by the row ref.
-   */
-  assert_node_ref_count (ref_model, &grandparent2, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  /* Referenced by the row ref and because its child level is built. */
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 2);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &parent2, 1);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 0);
-
-  path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
-  row_ref = gtk_tree_row_reference_new (sort_model, path);
-  gtk_tree_path_free (path);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  /* Referenced because the node is visible, its child level is built
-   * and referenced by the row ref.
-   */
-  assert_node_ref_count (ref_model, &grandparent2, 3);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  /* Referenced by the row ref and because its child level is built. */
-  assert_node_ref_count (ref_model, &parent2, 2);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent2, 1);
-
-  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-
-  gtk_tree_row_reference_free (row_ref);
-
-  assert_node_ref_count (ref_model, &grandparent1, 1);
-  assert_node_ref_count (ref_model, &grandparent2, 1);
-  assert_node_ref_count (ref_model, &parent1, 0);
-  assert_node_ref_count (ref_model, &iter_parent1, 0);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (sort_model);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_reorder_single (void)
-{
-  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
-  GtkTreeIter siter1, siter2, siter3, siter4, siter5;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_INT };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
-                                     0, 30, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
-                                     0, 40, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
-                                     0, 10, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
-                                     0, 20, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
-                                     0, 60, -1);
-
-  assert_root_level_unreferenced (ref_model);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter5);
-
-  assert_node_ref_count (ref_model, &iter1, 3);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &iter3, 4);
-  assert_node_ref_count (ref_model, &iter4, 1);
-  assert_node_ref_count (ref_model, &iter5, 2);
-
-  /* Sort */
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_ASCENDING);
-
-  assert_node_ref_count (ref_model, &iter1, 3);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &iter3, 4);
-  assert_node_ref_count (ref_model, &iter4, 1);
-  assert_node_ref_count (ref_model, &iter5, 2);
-
-  /* Re-translate the iters after sorting */
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter5);
-
-  assert_entire_model_referenced (ref_model, 1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (sort_model);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-ref_count_reorder_two (void)
-{
-  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
-  GtkTreeIter citer1, citer2, citer3, citer4, citer5;
-  GtkTreeIter siter1, siter2, siter3, siter4, siter5;
-  GtkTreeIter sciter1, sciter2, sciter3, sciter4, sciter5;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-  GType column_types[] = { G_TYPE_INT };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
-                                     0, 30, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
-                                     0, 40, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
-                                     0, 10, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
-                                     0, 20, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
-                                     0, 60, -1);
-
-  /* Child level */
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer1, &iter1, 0,
-                                     0, 30, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer2, &iter1, 1,
-                                     0, 40, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer3, &iter1, 2,
-                                     0, 10, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer4, &iter1, 3,
-                                     0, 20, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer5, &iter1, 4,
-                                     0, 60, -1);
-
-  assert_root_level_unreferenced (ref_model);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  assert_node_ref_count (ref_model, &iter1, 2);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &iter3, 1);
-  assert_node_ref_count (ref_model, &iter4, 1);
-  assert_node_ref_count (ref_model, &iter5, 1);
-
-  assert_level_referenced (ref_model, 1, &iter1);
-
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
-
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter1, &citer1);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter2, &citer2);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter3, &citer3);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter4, &citer4);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter5, &citer5);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter5);
-
-  assert_node_ref_count (ref_model, &iter1, 4);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &iter3, 4);
-  assert_node_ref_count (ref_model, &iter4, 1);
-  assert_node_ref_count (ref_model, &iter5, 2);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter3);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter3);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
-
-  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter1);
-
-  assert_node_ref_count (ref_model, &citer1, 2);
-  assert_node_ref_count (ref_model, &citer2, 1);
-  assert_node_ref_count (ref_model, &citer3, 3);
-  assert_node_ref_count (ref_model, &citer4, 1);
-  assert_node_ref_count (ref_model, &citer5, 4);
-
-  /* Sort */
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_ASCENDING);
-
-  assert_node_ref_count (ref_model, &iter1, 4);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &iter3, 4);
-  assert_node_ref_count (ref_model, &iter4, 1);
-  assert_node_ref_count (ref_model, &iter5, 2);
-
-  assert_node_ref_count (ref_model, &citer1, 2);
-  assert_node_ref_count (ref_model, &citer2, 1);
-  assert_node_ref_count (ref_model, &citer3, 3);
-  assert_node_ref_count (ref_model, &citer4, 1);
-  assert_node_ref_count (ref_model, &citer5, 4);
-
-  /* Re-translate the iters after sorting */
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
-
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter1, &citer1);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter2, &citer2);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter3, &citer3);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter4, &citer4);
-  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter5, &citer5);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter5);
-
-  assert_node_ref_count (ref_model, &iter1, 2);
-  assert_node_ref_count (ref_model, &iter2, 1);
-  assert_node_ref_count (ref_model, &iter3, 1);
-  assert_node_ref_count (ref_model, &iter4, 1);
-  assert_node_ref_count (ref_model, &iter5, 1);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter3);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter3);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
-
-  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter1);
-
-  assert_level_referenced (ref_model, 1, &iter1);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (sort_model);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-check_sort_order (GtkTreeModel *sort_model,
-                  GtkSortType   sort_order,
-                  const char   *parent_path)
-{
-  int prev_value;
-  GtkTreeIter siter;
-
-  if (!parent_path)
-    gtk_tree_model_get_iter_first (sort_model, &siter);
-  else
-    {
-      GtkTreePath *path;
-
-      path = gtk_tree_path_new_from_string (parent_path);
-      gtk_tree_path_append_index (path, 0);
-
-      gtk_tree_model_get_iter (sort_model, &siter, path);
-
-      gtk_tree_path_free (path);
-    }
-
-  if (sort_order == GTK_SORT_ASCENDING)
-    prev_value = -1;
-  else
-    prev_value = INT_MAX;
-
-  do
-    {
-      int value;
-
-      gtk_tree_model_get (sort_model, &siter, 0, &value, -1);
-      if (sort_order == GTK_SORT_ASCENDING)
-        g_assert (prev_value <= value);
-      else
-        g_assert (prev_value >= value);
-
-      prev_value = value;
-    }
-  while (gtk_tree_model_iter_next (sort_model, &siter));
-}
-
-static void
-rows_reordered_single_level (void)
-{
-  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-  SignalMonitor *monitor;
-  GtkTreePath *path;
-  GType column_types[] = { G_TYPE_INT };
-  int order[][5] =
-    {
-        { 2, 3, 0, 1, 4 },
-        { 4, 3, 2, 1, 0 },
-        { 2, 1, 4, 3, 0 }
-    };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
-                                     0, 30, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
-                                     0, 40, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
-                                     0, 10, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
-                                     0, 20, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
-                                     0, 60, -1);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  monitor = signal_monitor_new (sort_model);
-
-  /* Sort */
-  path = gtk_tree_path_new ();
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          path, order[0], 5);
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_ASCENDING);
-  signal_monitor_assert_is_empty (monitor);
-  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
-
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          path, order[1], 5);
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_DESCENDING);
-  signal_monitor_assert_is_empty (monitor);
-  check_sort_order (sort_model, GTK_SORT_DESCENDING, NULL);
-
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          path, order[2], 5);
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
-                                        GTK_SORT_ASCENDING);
-  signal_monitor_assert_is_empty (monitor);
-
-  gtk_tree_path_free (path);
-  signal_monitor_free (monitor);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (sort_model);
-
-  assert_entire_model_unreferenced (ref_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-rows_reordered_two_levels (void)
-{
-  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
-  GtkTreeIter citer1, citer2, citer3, citer4, citer5;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-  SignalMonitor *monitor;
-  GtkTreePath *path, *child_path;
-  GType column_types[] = { G_TYPE_INT };
-  int order[][5] =
-    {
-        { 2, 3, 0, 1, 4 },
-        { 4, 3, 2, 1, 0 },
-        { 2, 1, 4, 3, 0 }
-    };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
-                                     0, 30, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
-                                     0, 40, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
-                                     0, 10, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
-                                     0, 20, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
-                                     0, 60, -1);
-
-  /* Child level */
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer1, &iter1, 0,
-                                     0, 30, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer2, &iter1, 1,
-                                     0, 40, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer3, &iter1, 2,
-                                     0, 10, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer4, &iter1, 3,
-                                     0, 20, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer5, &iter1, 4,
-                                     0, 60, -1);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
-
-  monitor = signal_monitor_new (sort_model);
-
-  /* Sort */
-  path = gtk_tree_path_new ();
-  child_path = gtk_tree_path_new_from_indices (2, -1);
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          path, order[0], 5);
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          child_path, order[0], 5);
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_ASCENDING);
-  signal_monitor_assert_is_empty (monitor);
-  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
-  /* The parent node of the child level moved due to sorting */
-  check_sort_order (sort_model, GTK_SORT_ASCENDING, "2");
-
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          path, order[1], 5);
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          child_path, order[1], 5);
-  gtk_tree_path_free (child_path);
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_DESCENDING);
-  signal_monitor_assert_is_empty (monitor);
-  check_sort_order (sort_model, GTK_SORT_DESCENDING, NULL);
-  /* The parent node of the child level moved due to sorting */
-  check_sort_order (sort_model, GTK_SORT_DESCENDING, "2");
-
-  child_path = gtk_tree_path_new_from_indices (0, -1);
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          path, order[2], 5);
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          child_path, order[2], 5);
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
-                                        GTK_SORT_ASCENDING);
-  signal_monitor_assert_is_empty (monitor);
-
-  gtk_tree_path_free (path);
-  gtk_tree_path_free (child_path);
-  signal_monitor_free (monitor);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (sort_model);
-
-  g_object_unref (ref_model);
-}
-
-static void
-sorted_insert (void)
-{
-  GtkTreeIter iter1, iter2, iter3, iter4, iter5, new_iter;
-  GtkTreeModel *model;
-  GtkTreeModelRefCount *ref_model;
-  GtkTreeModel *sort_model;
-  GtkWidget *tree_view;
-  SignalMonitor *monitor;
-  GtkTreePath *path;
-  GType column_types[] = { G_TYPE_INT };
-  int order0[] = { 1, 2, 3, 0, 4, 5, 6 };
-
-  model = gtk_tree_model_ref_count_new ();
-  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
-
-  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
-                                   column_types);
-
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
-                                     0, 30, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
-                                     0, 40, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
-                                     0, 10, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
-                                     0, 20, -1);
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
-                                     0, 60, -1);
-
-  sort_model = gtk_tree_model_sort_new_with_model (model);
-  tree_view = gtk_tree_view_new_with_model (sort_model);
-
-  /* Sort */
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_ASCENDING);
-  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
-
-  monitor = signal_monitor_new (sort_model);
-
-  /* Insert a new item */
-  signal_monitor_append_signal (monitor, ROW_INSERTED, "4");
-  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &new_iter, NULL,
-                                     5, 0, 50, -1);
-  signal_monitor_assert_is_empty (monitor);
-  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
-
-  /* Sort the tree sort and append a new item */
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
-                                        0, GTK_SORT_ASCENDING);
-  check_sort_order (model, GTK_SORT_ASCENDING, NULL);
-
-  path = gtk_tree_path_new ();
-  signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
-  signal_monitor_append_signal_reordered (monitor,
-                                          ROWS_REORDERED,
-                                          path, order0, 7);
-  signal_monitor_append_signal (monitor, ROW_CHANGED, "3");
-  gtk_tree_store_append (GTK_TREE_STORE (model), &new_iter, NULL);
-  gtk_tree_store_set (GTK_TREE_STORE (model), &new_iter, 0, 35, -1);
-  check_sort_order (model, GTK_SORT_ASCENDING, NULL);
-  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
-
-  gtk_tree_path_free (path);
-  signal_monitor_free (monitor);
-
-  gtk_widget_destroy (tree_view);
-  g_object_unref (sort_model);
-
-  g_object_unref (ref_model);
-}
-
-
-static void
-specific_bug_300089 (void)
-{
-  /* Test case for GNOME Bugzilla bug 300089.  Written by
-   * Matthias Clasen.
-   */
-  GtkTreeModel *sort_model, *child_model;
-  GtkTreePath *path;
-  GtkTreeIter iter, iter2, sort_iter;
-
-  g_test_bug ("300089");
-
-  child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
-
-  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
-  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
-  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
-  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "B", -1);
-
-  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
-  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "D", -1);
-  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
-  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "E", -1);
-
-  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
-  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "C", -1);
-
-
-  sort_model = GTK_TREE_MODEL (gtk_tree_model_sort_new_with_model (child_model));
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-                                        0, GTK_SORT_ASCENDING);
-
-  path = gtk_tree_path_new_from_indices (1, 1, -1);
-
-  /* make sure a level is constructed */
-  gtk_tree_model_get_iter (sort_model, &sort_iter, path);
-
-  /* change the "E" row in a way that causes it to change position */ 
-  gtk_tree_model_get_iter (child_model, &iter, path);
-  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
-
-  gtk_tree_path_free (path);
-}
-
-static void
-specific_bug_364946 (void)
-{
-  /* This is a test case for GNOME Bugzilla bug 364946.  It was written
-   * by Andreas Koehler.
-   */
-  GtkTreeStore *store;
-  GtkTreeIter a, aa, aaa, aab, iter;
-  GtkTreeModel *s_model;
-
-  g_test_bug ("364946");
-
-  store = gtk_tree_store_new (1, G_TYPE_STRING);
-
-  gtk_tree_store_append (store, &a, NULL);
-  gtk_tree_store_set (store, &a, 0, "0", -1);
-
-  gtk_tree_store_append (store, &aa, &a);
-  gtk_tree_store_set (store, &aa, 0, "0:0", -1);
-
-  gtk_tree_store_append (store, &aaa, &aa);
-  gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
-
-  gtk_tree_store_append (store, &aab, &aa);
-  gtk_tree_store_set (store, &aab, 0, "0:0:1", -1);
-
-  s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model), 0,
-                                        GTK_SORT_ASCENDING);
-
-  gtk_tree_model_get_iter_from_string (s_model, &iter, "0:0:0");
-
-  gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
-  gtk_tree_store_remove (store, &aaa);
-  gtk_tree_store_remove (store, &aab);
-
-  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model));
-}
-
-static void
-iter_test (GtkTreeModel *model)
-{
-  GtkTreeIter a, b;
-
-  g_assert (gtk_tree_model_get_iter_first (model, &a));
-
-  g_assert (gtk_tree_model_iter_next (model, &a));
-  g_assert (gtk_tree_model_iter_next (model, &a));
-  b = a;
-  g_assert (!gtk_tree_model_iter_next (model, &b));
-
-  g_assert (gtk_tree_model_iter_previous (model, &a));
-  g_assert (gtk_tree_model_iter_previous (model, &a));
-  b = a;
-  g_assert (!gtk_tree_model_iter_previous (model, &b));
-}
-
-static void
-specific_bug_674587 (void)
-{
-  GtkListStore *l;
-  GtkTreeStore *t;
-  GtkTreeModel *m;
-  GtkTreeIter a;
-
-  l = gtk_list_store_new (1, G_TYPE_STRING);
-
-  gtk_list_store_append (l, &a);
-  gtk_list_store_set (l, &a, 0, "0", -1);
-  gtk_list_store_append (l, &a);
-  gtk_list_store_set (l, &a, 0, "1", -1);
-  gtk_list_store_append (l, &a);
-  gtk_list_store_set (l, &a, 0, "2", -1);
-
-  iter_test (GTK_TREE_MODEL (l));
-
-  g_object_unref (l);
-
-  t = gtk_tree_store_new (1, G_TYPE_STRING);
-
-  gtk_tree_store_append (t, &a, NULL);
-  gtk_tree_store_set (t, &a, 0, "0", -1);
-  gtk_tree_store_append (t, &a, NULL);
-  gtk_tree_store_set (t, &a, 0, "1", -1);
-  gtk_tree_store_append (t, &a, NULL);
-  gtk_tree_store_set (t, &a, 0, "2", -1);
-
-  iter_test (GTK_TREE_MODEL (t));
-
-  m = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (t));
-
-  iter_test (m);
-
-  g_object_unref (t);
-  g_object_unref (m);
-}
-
-static void
-row_deleted_cb (GtkTreeModel *tree_model,
-    GtkTreePath  *path,
-    guint *count)
-{
-  *count = *count + 1;
-}
-
-static void
-specific_bug_698846 (void)
-{
-  GtkListStore *store;
-  GtkTreeModel *sorted;
-  GtkTreeIter iter;
-  guint count = 0;
-
-  g_test_bug ("698846");
-
-  store = gtk_list_store_new (1, G_TYPE_STRING);
-  sorted = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
-
-  gtk_list_store_insert_with_values (store, &iter, 0, 0, "a", -1);
-  gtk_list_store_insert_with_values (store, &iter, 1, 0, "b", -1);
-
-  g_signal_connect (sorted, "row-deleted", G_CALLBACK (row_deleted_cb), &count);
-
-  gtk_list_store_clear (store);
-
-  g_assert_cmpuint (count, ==, 2);
-}
-
-/* main */
-
-void
-register_sort_model_tests (void)
-{
-  g_test_add_func ("/TreeModelSort/ref-count/single-level",
-                   ref_count_single_level);
-  g_test_add_func ("/TreeModelSort/ref-count/two-levels",
-                   ref_count_two_levels);
-  g_test_add_func ("/TreeModelSort/ref-count/three-levels",
-                   ref_count_three_levels);
-  g_test_add_func ("/TreeModelSort/ref-count/delete-row",
-                   ref_count_delete_row);
-  g_test_add_func ("/TreeModelSort/ref-count/cleanup",
-                   ref_count_cleanup);
-  g_test_add_func ("/TreeModelSort/ref-count/row-ref",
-                   ref_count_row_ref);
-  g_test_add_func ("/TreeModelSort/ref-count/reorder/single-level",
-                   ref_count_reorder_single);
-  g_test_add_func ("/TreeModelSort/ref-count/reorder/two-levels",
-                   ref_count_reorder_two);
-
-  g_test_add_func ("/TreeModelSort/rows-reordered/single-level",
-                   rows_reordered_single_level);
-  g_test_add_func ("/TreeModelSort/rows-reordered/two-levels",
-                   rows_reordered_two_levels);
-  g_test_add_func ("/TreeModelSort/sorted-insert",
-                   sorted_insert);
-
-  g_test_add_func ("/TreeModelSort/specific/bug-300089",
-                   specific_bug_300089);
-  g_test_add_func ("/TreeModelSort/specific/bug-364946",
-                   specific_bug_364946);
-  g_test_add_func ("/TreeModelSort/specific/bug-674587",
-                   specific_bug_674587);
-  g_test_add_func ("/TreeModelSort/specific/bug-698846",
-                   specific_bug_698846);
-}
-
diff --git a/gtk/tests/stylecontext.c b/gtk/tests/stylecontext.c
deleted file mode 100644 (file)
index 3435ce4..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-#include <gtk/gtk.h>
-
-static void
-test_parse_selectors (void)
-{
-  GtkCssProvider *provider;
-  GError *error;
-  gboolean res;
-  gint i;
-  const gchar *valid[] = {
-    "* {}",
-    "E {}",
-    "E F {}",
-    "E > F {}",
-    "E#id {}",
-    "#id {}",
-    "tab:first-child {}",
-    "tab:last-child {}",
-    "tab:nth-child(first) {}",
-    "tab:nth-child(last) {}",
-    "tab:nth-child(even) {}",
-    "tab:nth-child(odd) {}",
-    "tab:sorted {}",
-    ".some-class {}",
-    ".some-class.another-class {}",
-    ".some-class .another-class {}",
-    "E * {}",
-    "E .class {}",
-    "E > .foo {}",
-    "E > #id {}",
-    "E:active {}",
-    "E:prelight {}",
-    "E:hover {}",
-    "E:selected {}",
-    "E:insensitive {}",
-    "E:inconsistent {}",
-    "E:focused {}",
-    "E:active:prelight {}",
-    "* > .notebook tab:first-child .label:focused {}",
-    "E, F {}",
-    "E, F /* comment here */ {}",
-    "E,/* comment here */ F {}",
-    "E1.e1_2 #T3_4 {}",
-    "E:first-child {}",
-    "E:last-child {}",
-    "E:nth-child(first) {}",
-    "E:nth-child(last) {}",
-    "E:nth-child(even) {}",
-    "E:nth-child(odd) {}",
-    "E:sorted {}",
-    "E:focused tab {}",
-     NULL
-  };
-
-  error = NULL;
-  for (i = 0; valid[i]; i++)
-    {
-      provider = gtk_css_provider_new ();
-      res = gtk_css_provider_load_from_data (provider, valid[i], -1, &error);
-      if (error)
-        g_print ("parsing '%s': got unexpected error: %s\n", valid[i], error->message);
-      g_assert_no_error (error);
-      g_assert (res);
-
-      g_object_unref (provider);
-   }
-}
-
-static void
-test_path (void)
-{
-  GtkWidgetPath *path;
-  GtkWidgetPath *path2;
-  gint pos;
-  GtkRegionFlags flags;
-
-  path = gtk_widget_path_new ();
-  g_assert_cmpint (gtk_widget_path_length (path), ==, 0);
-
-  pos = gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
-  g_assert_cmpint (pos, ==, 0);
-  g_assert_cmpint (gtk_widget_path_length (path), ==, 1);
-  g_assert (gtk_widget_path_iter_get_object_type (path, 0) == GTK_TYPE_WINDOW);
-  g_assert (gtk_widget_path_is_type (path, GTK_TYPE_WIDGET));
-  g_assert (gtk_widget_path_iter_get_name (path, 0) == NULL);
-
-  pos = gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
-  g_assert_cmpint (pos, ==, 1);
-  g_assert_cmpint (gtk_widget_path_length (path), ==, 2);
-  gtk_widget_path_iter_set_object_type (path, pos, GTK_TYPE_BUTTON);
-  g_assert (gtk_widget_path_is_type (path, GTK_TYPE_BUTTON));
-  g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WIDGET));
-  g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WINDOW));
-  g_assert (!gtk_widget_path_has_parent (path, GTK_TYPE_DIALOG));
-  g_assert (gtk_widget_path_iter_get_name (path, 1) == NULL);
-
-  gtk_widget_path_iter_set_name (path, 1, "name");
-  g_assert (gtk_widget_path_iter_has_name (path, 1, "name"));
-
-  gtk_widget_path_iter_add_class (path, 1, "class1");
-  gtk_widget_path_iter_add_class (path, 1, "class2");
-  g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
-  g_assert (gtk_widget_path_iter_has_class (path, 1, "class2"));
-  g_assert (!gtk_widget_path_iter_has_class (path, 1, "class3"));
-
-  path2 = gtk_widget_path_copy (path);
-  g_assert (gtk_widget_path_iter_has_class (path2, 1, "class1"));
-  g_assert (gtk_widget_path_iter_has_class (path2, 1, "class2"));
-  g_assert (!gtk_widget_path_iter_has_class (path2, 1, "class3"));
-  gtk_widget_path_free (path2);
-
-  gtk_widget_path_iter_remove_class (path, 1, "class2");
-  g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
-  g_assert (!gtk_widget_path_iter_has_class (path, 1, "class2"));
-  gtk_widget_path_iter_clear_classes (path, 1);
-  g_assert (!gtk_widget_path_iter_has_class (path, 1, "class1"));
-
-  gtk_widget_path_iter_add_region (path, 1, "tab", 0);
-  gtk_widget_path_iter_add_region (path, 1, "title", GTK_REGION_EVEN | GTK_REGION_FIRST);
-
-  g_assert (gtk_widget_path_iter_has_region (path, 1, "tab", &flags) &&
-            flags == 0);
-  g_assert (gtk_widget_path_iter_has_region (path, 1, "title", &flags) &&
-            flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
-  g_assert (!gtk_widget_path_iter_has_region (path, 1, "extension", NULL));
-
-  path2 = gtk_widget_path_copy (path);
-  g_assert (gtk_widget_path_iter_has_region (path2, 1, "tab", &flags) &&
-            flags == 0);
-  g_assert (gtk_widget_path_iter_has_region (path2, 1, "title", &flags) &&
-            flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
-  g_assert (!gtk_widget_path_iter_has_region (path2, 1, "extension", NULL));
-  gtk_widget_path_free (path2);
-
-  gtk_widget_path_free (path);
-}
-
-static void
-test_match (void)
-{
-  GtkStyleContext *context;
-  GtkWidgetPath *path;
-  GtkCssProvider *provider;
-  GError *error;
-  const gchar *data;
-  GdkRGBA color;
-  GdkRGBA expected;
-
-  error = NULL;
-  provider = gtk_css_provider_new ();
-
-  gdk_rgba_parse (&expected, "#fff");
-
-  context = gtk_style_context_new ();
-
-  path = gtk_widget_path_new ();
-  gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
-  gtk_widget_path_append_type (path, GTK_TYPE_BOX);
-  gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
-  gtk_widget_path_iter_set_name (path, 0, "mywindow");
-  gtk_widget_path_iter_add_class (path, 2, "button");
-  gtk_style_context_set_path (context, path);
-  gtk_widget_path_free (path);
-
-  gtk_style_context_add_provider (context,
-                                  GTK_STYLE_PROVIDER (provider),
-                                  GTK_STYLE_PROVIDER_PRIORITY_USER);
-
-  data = "* { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         "GtkButton { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         "GtkButton { color: #fff }\n"
-         "GtkWindow > GtkButton { color: #000 }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         ".button { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         "GtkButton { color: #000 }\n"
-         ".button { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         "GtkButton { color: #000 }\n"
-         "GtkWindow GtkButton { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         ".button { color: #000 }\n"
-         "GtkWindow .button { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         "* .button { color: #000 }\n"
-         "#mywindow .button { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         "GtkWindow .button { color: #000 }\n"
-         "GtkWindow#mywindow .button { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  data = "* { color: #f00 }\n"
-         "GtkWindow .button { color: #000 }\n"
-         "GObject .button { color: #fff }";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_invalidate (context);
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  g_object_unref (provider);
-  g_object_unref (context);
-}
-
-static void
-test_style_property (void)
-{
-  GtkStyleContext *context;
-  GtkWidgetPath *path;
-  GtkCssProvider *provider;
-  GError *error;
-  const gchar *data;
-  gint x;
-  GdkRGBA color;
-  GdkRGBA expected;
-
-  error = NULL;
-  provider = gtk_css_provider_new ();
-
-  context = gtk_style_context_new ();
-
-  path = gtk_widget_path_new ();
-  gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
-  gtk_widget_path_append_type (path, GTK_TYPE_BOX);
-  gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
-  gtk_style_context_set_path (context, path);
-  gtk_widget_path_free (path);
-  gtk_style_context_set_state (context, GTK_STATE_FLAG_PRELIGHT);
-
-  /* Since we set the prelight state on the context, we expect
-   * only the third selector to match, even though the second one
-   * has higher specificity, and the fourth one comes later.
-   *
-   * In particular, we want to verify that widget style properties and
-   * CSS properties follow the same matching rules, ie we expect
-   * color to be #003 and child-displacement-x to be 3.
-   */
-  data = "GtkButton:insensitive { color: #001; -GtkButton-child-displacement-x: 1 }\n"
-         "GtkBox GtkButton:selected { color: #002; -GtkButton-child-displacement-x: 2 }\n"
-         "GtkButton:prelight { color: #003; -GtkButton-child-displacement-x: 3 }\n"
-         "GtkButton:focused { color: #004; -GtkButton-child-displacement-x: 4 }\n";
-  gtk_css_provider_load_from_data (provider, data, -1, &error);
-  g_assert_no_error (error);
-  gtk_style_context_add_provider (context,
-                                  GTK_STYLE_PROVIDER (provider),
-                                  GTK_STYLE_PROVIDER_PRIORITY_USER);
-
-  gtk_style_context_invalidate (context);
-
-  gtk_style_context_get_color (context, GTK_STATE_FLAG_PRELIGHT, &color);
-  gdk_rgba_parse (&expected, "#003");
-  g_assert (gdk_rgba_equal (&color, &expected));
-
-  gtk_style_context_get_style (context, "child-displacement-x", &x, NULL);
-
-  g_assert_cmpint (x, ==, 3);
-
-  g_object_unref (provider);
-  g_object_unref (context);
-}
-
-static void
-test_basic_properties (void)
-{
-  GtkStyleContext *context;
-  GtkWidgetPath *path;
-  GdkRGBA *color;
-  GdkRGBA *bg_color;
-  PangoFontDescription *font;
-
-  context = gtk_style_context_new ();
-  path = gtk_widget_path_new ();
-  gtk_style_context_set_path (context, path);
-  gtk_widget_path_free (path);
-
-  gtk_style_context_get (context, 0,
-                         "color", &color,
-                         "background-color", &bg_color,
-                         "font", &font,
-                         NULL);
-  g_assert (color != NULL);
-  g_assert (bg_color != NULL);
-  g_assert (font != NULL);
-
-  gdk_rgba_free (color);
-  gdk_rgba_free (bg_color);
-  pango_font_description_free (font);
-
-  g_object_unref (context);
-}
-
-int
-main (int argc, char *argv[])
-{
-  gtk_init (NULL, NULL);
-  g_test_init (&argc, &argv, NULL);
-
-  g_test_add_func ("/style/parse/selectors", test_parse_selectors);
-  g_test_add_func ("/style/path", test_path);
-  g_test_add_func ("/style/match", test_match);
-  g_test_add_func ("/style/style-property", test_style_property);
-  g_test_add_func ("/style/basic", test_basic_properties);
-
-  return g_test_run ();
-}
diff --git a/gtk/tests/templates.c b/gtk/tests/templates.c
deleted file mode 100644 (file)
index 32c1e68..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/* templates.c
- * Copyright (C) 2013 Openismus GmbH
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Tristan Van Berkom <tristanvb@openismus.com>
- */
-#include <gtk/gtk.h>
-
-#ifdef HAVE_UNIX_PRINT_WIDGETS
-#  include <gtk/gtkunixprint.h>
-#endif
-
-static gboolean
-main_loop_quit_cb (gpointer data)
-{
-  gtk_main_quit ();
-
-  return FALSE;
-}
-
-static void
-test_dialog_basic (void)
-{
-  GtkWidget *dialog;
-
-  dialog = gtk_dialog_new();
-  g_assert (GTK_IS_DIALOG (dialog));
-  g_assert (gtk_dialog_get_action_area (GTK_DIALOG (dialog)) != NULL);
-  g_assert (gtk_dialog_get_content_area (GTK_DIALOG (dialog)) != NULL);
-
-  gtk_widget_destroy (dialog);
-}
-
-static void
-test_dialog_override_property (void)
-{
-  GtkWidget *dialog;
-
-  dialog = g_object_new (GTK_TYPE_DIALOG,
-                        "type-hint", GDK_WINDOW_TYPE_HINT_UTILITY,
-                        NULL);
-  g_assert (GTK_IS_DIALOG (dialog));
-  g_assert (gtk_window_get_type_hint (GTK_WINDOW (dialog)) == GDK_WINDOW_TYPE_HINT_UTILITY);
-
-  gtk_widget_destroy (dialog);
-}
-
-static void
-test_message_dialog_basic (void)
-{
-  GtkWidget *dialog;
-
-  dialog = gtk_message_dialog_new (NULL, 0,
-                                  GTK_MESSAGE_INFO,
-                                  GTK_BUTTONS_CLOSE,
-                                  "Do it hard !");
-  g_assert (GTK_IS_DIALOG (dialog));
-  gtk_widget_destroy (dialog);
-}
-
-static void
-test_about_dialog_basic (void)
-{
-  GtkWidget *dialog;
-
-  dialog = gtk_about_dialog_new ();
-  g_assert (GTK_IS_ABOUT_DIALOG (dialog));
-  gtk_widget_destroy (dialog);
-}
-
-static void
-test_info_bar_basic (void)
-{
-  GtkWidget *infobar;
-
-  infobar = gtk_info_bar_new ();
-  g_assert (GTK_IS_INFO_BAR (infobar));
-  gtk_widget_destroy (infobar);
-}
-
-static void
-test_lock_button_basic (void)
-{
-  GtkWidget *button;
-  GPermission *permission;
-
-  permission = g_simple_permission_new (TRUE);
-  button = gtk_lock_button_new (permission);
-  g_assert (GTK_IS_LOCK_BUTTON (button));
-  gtk_widget_destroy (button);
-  g_object_unref (permission);
-}
-
-static void
-test_assistant_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_assistant_new ();
-  g_assert (GTK_IS_ASSISTANT (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_scale_button_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_scale_button_new (GTK_ICON_SIZE_MENU,
-                                0, 100, 10, NULL);
-  g_assert (GTK_IS_SCALE_BUTTON (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_volume_button_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_volume_button_new ();
-  g_assert (GTK_IS_VOLUME_BUTTON (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_statusbar_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_statusbar_new ();
-  g_assert (GTK_IS_STATUSBAR (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_app_chooser_widget_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_app_chooser_widget_new (NULL);
-  g_assert (GTK_IS_APP_CHOOSER_WIDGET (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_app_chooser_dialog_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_app_chooser_dialog_new_for_content_type (NULL, 0, "text/plain");
-  g_assert (GTK_IS_APP_CHOOSER_DIALOG (widget));
-
-  /* GtkAppChooserDialog bug, if destroyed before spinning 
-   * the main context then app_chooser_online_get_default_ready_cb()
-   * will be eventually called and segfault.
-   */
-  g_timeout_add (500, main_loop_quit_cb, NULL);
-  gtk_main();
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_color_chooser_dialog_basic (void)
-{
-  GtkWidget *widget;
-
-  /* This test also tests the internal GtkColorEditor widget */
-  widget = gtk_color_chooser_dialog_new (NULL, NULL);
-  g_assert (GTK_IS_COLOR_CHOOSER_DIALOG (widget));
-  gtk_widget_destroy (widget);
-}
-
-/* Avoid warnings from GVFS-RemoteVolumeMonitor */
-static gboolean
-ignore_gvfs_warning (const gchar *log_domain,
-                    GLogLevelFlags log_level,
-                    const gchar *message,
-                    gpointer user_data)
-{
-  if (g_strcmp0 (log_domain, "GVFS-RemoteVolumeMonitor") == 0)
-    return FALSE;
-
-  return TRUE;
-}
-
-static void
-test_file_chooser_widget_basic (void)
-{
-  GtkWidget *widget;
-
-  /* This test also tests the internal GtkPathBar widget */
-  g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
-
-  widget = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
-  g_assert (GTK_IS_FILE_CHOOSER_WIDGET (widget));
-
-  /* XXX BUG:
-   *
-   * Spin the mainloop for a bit, this allows the file operations
-   * to complete, GtkFileChooserDefault has a bug where it leaks
-   * GtkTreeRowReferences to the internal shortcuts_model
-   *
-   * Since we assert all automated children are finalized we
-   * can catch this
-   */
-  g_timeout_add (100, main_loop_quit_cb, NULL);
-  gtk_main();
-
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_file_chooser_dialog_basic (void)
-{
-  GtkWidget *widget;
-
-  g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
-
-  widget = gtk_file_chooser_dialog_new ("The Dialog", NULL,
-                                       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-                                       GTK_STOCK_OK, GTK_RESPONSE_OK,
-                                       NULL);
-
-  g_assert (GTK_IS_FILE_CHOOSER_DIALOG (widget));
-  g_timeout_add (100, main_loop_quit_cb, NULL);
-  gtk_main();
-
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_file_chooser_button_basic (void)
-{
-  GtkWidget *widget;
-
-  g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
-
-  widget = gtk_file_chooser_button_new ("Choose a file !", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
-  g_assert (GTK_IS_FILE_CHOOSER_BUTTON (widget));
-  g_timeout_add (100, main_loop_quit_cb, NULL);
-  gtk_main();
-
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_font_button_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_font_button_new ();
-  g_assert (GTK_IS_FONT_BUTTON (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_font_chooser_widget_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_font_chooser_widget_new ();
-  g_assert (GTK_IS_FONT_CHOOSER_WIDGET (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_font_chooser_dialog_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_font_chooser_dialog_new ("Choose a font !", NULL);
-  g_assert (GTK_IS_FONT_CHOOSER_DIALOG (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_recent_chooser_widget_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_recent_chooser_widget_new ();
-  g_assert (GTK_IS_RECENT_CHOOSER_WIDGET (widget));
-  gtk_widget_destroy (widget);
-}
-
-#ifdef HAVE_UNIX_PRINT_WIDGETS
-static void
-test_page_setup_unix_dialog_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_page_setup_unix_dialog_new ("Setup your Page !", NULL);
-  g_assert (GTK_IS_PAGE_SETUP_UNIX_DIALOG (widget));
-  gtk_widget_destroy (widget);
-}
-
-static void
-test_print_unix_dialog_basic (void)
-{
-  GtkWidget *widget;
-
-  widget = gtk_print_unix_dialog_new ("Go Print !", NULL);
-  g_assert (GTK_IS_PRINT_UNIX_DIALOG (widget));
-  gtk_widget_destroy (widget);
-}
-#endif
-
-int
-main (int argc, char **argv)
-{
-  /* initialize test program */
-  gtk_test_init (&argc, &argv);
-
-  /* This environment variable cooperates with gtk_widget_destroy()
-   * to assert that all automated compoenents are properly finalized
-   * when a given composite widget is destroyed.
-   */
-  g_assert (g_setenv ("GTK_WIDGET_ASSERT_COMPONENTS", "1", TRUE));
-
-  g_test_add_func ("/Template/GtkDialog/Basic", test_dialog_basic);
-  g_test_add_func ("/Template/GtkDialog/OverrideProperty", test_dialog_override_property);
-  g_test_add_func ("/Template/GtkMessageDialog/Basic", test_message_dialog_basic);
-  g_test_add_func ("/Template/GtkAboutDialog/Basic", test_about_dialog_basic);
-  g_test_add_func ("/Template/GtkInfoBar/Basic", test_info_bar_basic);
-  g_test_add_func ("/Template/GtkLockButton/Basic", test_lock_button_basic);
-  g_test_add_func ("/Template/GtkAssistant/Basic", test_assistant_basic);
-  g_test_add_func ("/Template/GtkScaleButton/Basic", test_scale_button_basic);
-  g_test_add_func ("/Template/GtkVolumeButton/Basic", test_volume_button_basic);
-  g_test_add_func ("/Template/GtkStatusBar/Basic", test_statusbar_basic);
-  g_test_add_func ("/Template/GtkAppChooserWidget/Basic", test_app_chooser_widget_basic);
-  g_test_add_func ("/Template/GtkAppChooserDialog/Basic", test_app_chooser_dialog_basic);
-  g_test_add_func ("/Template/GtkColorChooserDialog/Basic", test_color_chooser_dialog_basic);
-  g_test_add_func ("/Template/GtkFileChooserWidget/Basic", test_file_chooser_widget_basic);
-  g_test_add_func ("/Template/GtkFileChooserDialog/Basic", test_file_chooser_dialog_basic);
-  g_test_add_func ("/Template/GtkFileChooserButton/Basic", test_file_chooser_button_basic);
-  g_test_add_func ("/Template/GtkFontButton/Basic", test_font_button_basic);
-  g_test_add_func ("/Template/GtkFontChooserWidget/Basic", test_font_chooser_widget_basic);
-  g_test_add_func ("/Template/GtkFontChooserDialog/Basic", test_font_chooser_dialog_basic);
-  g_test_add_func ("/Template/GtkRecentChooserWidget/Basic", test_recent_chooser_widget_basic);
-
-#ifdef HAVE_UNIX_PRINT_WIDGETS
-  g_test_add_func ("/Template/UnixPrint/GtkPageSetupUnixDialog/Basic", test_page_setup_unix_dialog_basic);
-  g_test_add_func ("/Template/UnixPrint/GtkPrintUnixDialog/Basic", test_print_unix_dialog_basic);
-#endif
-
-  return g_test_run();
-}
diff --git a/gtk/tests/testing.c b/gtk/tests/testing.c
deleted file mode 100644 (file)
index ed67615..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/* Gtk+ testing utilities
- * Copyright (C) 2007 Imendio AB
- * Authors: Tim Janik
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <string.h>
-#include <math.h>
-
-/* Use a keyval that requires Shift to be active (in typical layouts)
- * like GDK_KEY_ampersand, which is '<shift>6'
- */
-#define KEYVAL_THAT_REQUIRES_SHIFT GDK_KEY_ampersand
-
-
-/* --- test functions --- */
-static void
-test_button_clicks (void)
-{
-  int a = 0, b = 0, c = 0;
-  GtkWidget *window = gtk_test_display_button_window ("Test Window",
-                                                      "Test: gtk_test_widget_click",
-                                                      "IgnoreMe1", &a,
-                                                      "ClickMe", &b,
-                                                      "IgnoreMe2", &c,
-                                                      NULL);
-  GtkWidget *button = gtk_test_find_widget (window, "*Click*", GTK_TYPE_BUTTON);
-  gboolean simsuccess;
-  g_assert (button != NULL);
-  simsuccess = gtk_test_widget_click (button, 1, 0);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-  g_assert (a == 0);
-  g_assert (b > 0);
-  g_assert (c == 0);
-}
-
-static void
-test_button_keys (void)
-{
-  int a = 0, b = 0, c = 0;
-  GtkWidget *window = gtk_test_display_button_window ("Test Window",
-                                                      "Test: gtk_test_widget_send_key",
-                                                      "IgnoreMe1", &a,
-                                                      "ClickMe", &b,
-                                                      "IgnoreMe2", &c,
-                                                      NULL);
-  GtkWidget *button = gtk_test_find_widget (window, "*Click*", GTK_TYPE_BUTTON);
-  gboolean simsuccess;
-  g_assert (button != NULL);
-  gtk_widget_grab_focus (button);
-  g_assert (gtk_widget_has_focus (button));
-  simsuccess = gtk_test_widget_send_key (button, GDK_KEY_Return, 0);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-  g_assert (a == 0);
-  g_assert (b > 0);
-  g_assert (c == 0);
-}
-
-static gboolean
-store_last_key_release (GtkWidget   *widget,
-                        GdkEventKey *event,
-                        gpointer     user_data)
-{
-  *((gint *)user_data) = event->keyval;
-  return FALSE;
-}
-
-static void
-test_send_shift_key (void)
-{
-  GtkWidget *window = gtk_test_display_button_window ("Test Window",
-                                                      "Test: test_send_shift_key()",
-                                                      "IgnoreMe1", NULL,
-                                                      "SendMeKeys", NULL,
-                                                      "IgnoreMe2", NULL,
-                                                      NULL);
-  GtkWidget *button = gtk_test_find_widget (window, "SendMeKeys", GTK_TYPE_BUTTON);
-  gint last_key_release = 0;
-  gboolean simsuccess;
-  g_assert (button != NULL);
-  g_signal_connect (button, "key-release-event",
-                    G_CALLBACK (store_last_key_release),
-                    &last_key_release);
-  gtk_widget_grab_focus (button);
-  g_assert (gtk_widget_has_focus (button));
-  simsuccess = gtk_test_widget_send_key (button, KEYVAL_THAT_REQUIRES_SHIFT, 0 /*modifiers*/);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-  g_assert_cmpint (KEYVAL_THAT_REQUIRES_SHIFT, ==, last_key_release);
-}
-
-static void
-test_slider_ranges (void)
-{
-  GtkWidget *child;
-  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: gtk_test_warp_slider");
-  GtkWidget *hscale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
-                                                -50, +50, 5);
-
-  child = gtk_bin_get_child (GTK_BIN (window));
-  gtk_container_add (GTK_CONTAINER (child), hscale);
-  gtk_widget_show (hscale);
-  gtk_widget_show_now (window);
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-  gtk_test_slider_set_perc (hscale, 0.0);
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-  g_assert (gtk_test_slider_get_value (hscale) == -50);
-  gtk_test_slider_set_perc (hscale, 50.0);
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-  g_assert (fabs (gtk_test_slider_get_value (hscale)) < 0.0001);
-  gtk_test_slider_set_perc (hscale, 100.0);
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-  g_assert (gtk_test_slider_get_value (hscale) == +50.0);
-}
-
-static void
-test_text_access (void)
-{
-  const int N_WIDGETS = 3;
-  GtkWidget *widgets[N_WIDGETS];
-  int i = 0;
-  widgets[i++] = gtk_test_create_widget (GTK_TYPE_LABEL, NULL);
-  widgets[i++] = gtk_test_create_widget (GTK_TYPE_ENTRY, NULL);
-  widgets[i++] = gtk_test_create_widget (GTK_TYPE_TEXT_VIEW, NULL);
-  g_assert (i == N_WIDGETS);
-  for (i = 0; i < N_WIDGETS; i++)
-    gtk_test_text_set (widgets[i], "foobar");
-  for (i = 0; i < N_WIDGETS; i++)
-    {
-      gchar *text  = gtk_test_text_get (widgets[i]);
-      g_assert (strcmp (text, "foobar") == 0);
-      g_free (text);
-    }
-  for (i = 0; i < N_WIDGETS; i++)
-    gtk_test_text_set (widgets[i], "");
-  for (i = 0; i < N_WIDGETS; i++)
-    {
-      gchar *text  = gtk_test_text_get (widgets[i]);
-      g_assert (strcmp (text, "") == 0);
-      g_free (text);
-    }
-}
-
-static void
-test_xserver_sync (void)
-{
-  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: test_xserver_sync");
-  GtkWidget *darea = gtk_drawing_area_new ();
-  GtkWidget *child;
-  GdkWindow *gdk_window;
-  GTimer *gtimer = g_timer_new();
-  gint sync_is_slower = 0, repeat = 5;
-
-  child = gtk_bin_get_child (GTK_BIN (window));
-  //gdk_window = gtk_widget_get_window (darea);
-
-  gtk_widget_set_size_request (darea, 320, 200);
-  gtk_container_add (GTK_CONTAINER (child), darea);
-  gtk_widget_show (darea);
-  gtk_widget_show_now (window);
-
-  while (repeat--)
-    {
-      gint i, many = 200;
-      double nosync_time, sync_time;
-      cairo_t *cr;
-
-      while (gtk_events_pending ())
-        gtk_main_iteration ();
-      gdk_window = gtk_widget_get_window (darea);
-      cr = gdk_cairo_create (gdk_window);
-      cairo_set_source_rgba (cr, 0, 1, 0, 0.1);
-      /* run a number of consecutive drawing requests, just using drawing queue */
-      g_timer_start (gtimer);
-      for (i = 0; i < many; i++)
-        {
-          cairo_paint (cr);
-        }
-      g_timer_stop (gtimer);
-      nosync_time = g_timer_elapsed (gtimer, NULL);
-      gdk_flush();
-      while (gtk_events_pending ())
-        gtk_main_iteration ();
-      g_timer_start (gtimer);
-      /* run a number of consecutive drawing requests with intermediate drawing syncs */
-      for (i = 0; i < many; i++)
-        {
-          cairo_paint (cr);
-          gdk_test_render_sync (gdk_window);
-        }
-      g_timer_stop (gtimer);
-      sync_time = g_timer_elapsed (gtimer, NULL);
-      sync_is_slower += sync_time > nosync_time * 1.5;
-    }
-  g_timer_destroy (gtimer);
-  g_assert (sync_is_slower > 0);
-}
-
-static void
-test_spin_button_arrows (void)
-{
-  GtkWidget *child;
-  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: test_spin_button_arrows");
-  GtkWidget *spinner = gtk_spin_button_new_with_range (0, 100, 5);
-  gboolean simsuccess;
-  double oldval, newval;
-
-  gtk_window_set_has_resize_grip (GTK_WINDOW (window), FALSE);
-
-  child = gtk_bin_get_child (GTK_BIN (window));
-  gtk_container_add (GTK_CONTAINER (child), spinner);
-  gtk_widget_show (spinner);
-  gtk_widget_show_now (window);
-  gtk_test_slider_set_perc (spinner, 0);
-  /* check initial spinner value */
-  oldval = gtk_test_slider_get_value (spinner);
-  g_assert (oldval == 0);
-  /* check simple increment */
-  simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 1, TRUE);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
-    gtk_main_iteration ();
-  newval = gtk_test_slider_get_value (spinner);
-  g_assert (newval > oldval);
-  /* check maximum warp */
-  simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 3, TRUE);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
-    gtk_main_iteration ();
-  oldval = gtk_test_slider_get_value (spinner);
-  g_assert (oldval == 100);
-  /* check simple decrement */
-  oldval = gtk_test_slider_get_value (spinner);
-  simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 1, FALSE);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
-    gtk_main_iteration ();
-  newval = gtk_test_slider_get_value (spinner);
-  g_assert (newval < oldval);
-  /* check minimum warp */
-  simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 3, FALSE);
-  g_assert (simsuccess == TRUE);
-  while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
-    gtk_main_iteration ();
-  oldval = gtk_test_slider_get_value (spinner);
-  g_assert (oldval == 0);
-}
-
-static void
-test_statusbar_remove_all (void)
-{
-  GtkWidget *statusbar;
-
-  g_test_bug ("640487");
-
-  statusbar = gtk_statusbar_new ();
-  g_object_ref_sink (statusbar);
-
-  gtk_statusbar_push (GTK_STATUSBAR (statusbar), 1, "bla");
-  gtk_statusbar_push (GTK_STATUSBAR (statusbar), 1, "bla");
-  gtk_statusbar_remove_all (GTK_STATUSBAR (statusbar), 1);
-
-  g_object_unref (statusbar);
-}
-
-int
-main (int   argc,
-      char *argv[])
-{
-  gtk_test_init (&argc, &argv);
-  g_test_bug_base ("http://bugzilla.gnome.org/");
-  gtk_test_register_all_types();
-
-  g_test_add_func ("/tests/statusbar-remove-all", test_statusbar_remove_all);
-  g_test_add_func ("/ui-tests/text-access", test_text_access);
-  g_test_add_func ("/ui-tests/button-clicks", test_button_clicks);
-  g_test_add_func ("/ui-tests/keys-events", test_button_keys);
-  g_test_add_func ("/ui-tests/send-shift-key", test_send_shift_key);
-  g_test_add_func ("/ui-tests/slider-ranges", test_slider_ranges);
-  g_test_add_func ("/ui-tests/xserver-sync", test_xserver_sync);
-  g_test_add_func ("/ui-tests/spin-button-arrows", test_spin_button_arrows);
-
-  return g_test_run();
-}
diff --git a/gtk/tests/textbuffer.c b/gtk/tests/textbuffer.c
deleted file mode 100644 (file)
index e26a5dd..0000000
+++ /dev/null
@@ -1,1341 +0,0 @@
-/* testtextbuffer.c -- Simplistic test suite
- * Copyright (C) 2000 Red Hat, Inc
- * Author: Havoc Pennington
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include "gtk/gtktexttypes.h" /* Private header, for UNKNOWN_CHAR */
-
-static void
-gtk_text_iter_spew (const GtkTextIter *iter, const gchar *desc)
-{
-  g_print (" %20s: line %d / char %d / line char %d / line byte %d\n",
-           desc,
-           gtk_text_iter_get_line (iter),
-           gtk_text_iter_get_offset (iter),
-           gtk_text_iter_get_line_offset (iter),
-           gtk_text_iter_get_line_index (iter));
-}
-
-static void
-check_get_set_text (GtkTextBuffer *buffer,
-                    const char    *str)
-{
-  GtkTextIter start, end, iter;
-  char *text;
-  int n;
-  
-  gtk_text_buffer_set_text (buffer, str, -1);
-  if (gtk_text_buffer_get_char_count (buffer) != g_utf8_strlen (str, -1))
-    g_error ("Wrong number of chars (%d not %d)",
-             gtk_text_buffer_get_char_count (buffer),
-             (int) g_utf8_strlen (str, -1));
-  gtk_text_buffer_get_bounds (buffer, &start, &end);
-  text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
-  if (strcmp (text, str) != 0)
-    g_error ("Got '%s' as buffer contents", text);
-  g_free (text);
-
-  /* line char counts */
-  iter = start;
-  n = 0;
-  do
-    {
-      n += gtk_text_iter_get_chars_in_line (&iter);
-    }
-  while (gtk_text_iter_forward_line (&iter));
-
-  if (n != gtk_text_buffer_get_char_count (buffer))
-    g_error ("Sum of chars in lines is %d but buffer char count is %d",
-             n, gtk_text_buffer_get_char_count (buffer));
-
-  /* line byte counts */
-  iter = start;
-  n = 0;
-  do
-    {
-      n += gtk_text_iter_get_bytes_in_line (&iter);
-    }
-  while (gtk_text_iter_forward_line (&iter));
-
-  if (n != strlen (str))
-    g_error ("Sum of chars in lines is %d but buffer byte count is %d",
-             n, (int) strlen (str));
-  
-  gtk_text_buffer_set_text (buffer, "", -1);
-
-  n = gtk_text_buffer_get_line_count (buffer);
-  if (n != 1)
-    g_error ("%d lines, expected 1", n);
-
-  n = gtk_text_buffer_get_char_count (buffer);
-  if (n != 0)
-    g_error ("%d chars, expected 0", n);
-}
-
-static gint
-count_toggles_at_iter (GtkTextIter *iter,
-                       GtkTextTag  *of_tag)
-{
-  GSList *tags;
-  GSList *tmp;
-  gint count = 0;
-  
-  /* get toggle-ons and toggle-offs */
-  tags = gtk_text_iter_get_toggled_tags (iter, TRUE);
-  tags = g_slist_concat (tags,
-                         gtk_text_iter_get_toggled_tags (iter, FALSE));
-  
-  tmp = tags;
-  while (tmp != NULL)
-    {
-      if (of_tag == NULL)
-        ++count;
-      else if (of_tag == tmp->data)
-        ++count;
-      
-      tmp = g_slist_next (tmp);
-    }
-  
-  g_slist_free (tags);
-
-  return count;
-}
-
-static gint
-count_toggles_in_range_by_char (GtkTextBuffer     *buffer,
-                                GtkTextTag        *of_tag,
-                                const GtkTextIter *start,
-                                const GtkTextIter *end)
-{
-  GtkTextIter iter;
-  gint count = 0;
-  
-  iter = *start;
-  do
-    {
-      count += count_toggles_at_iter (&iter, of_tag);
-      if (!gtk_text_iter_forward_char (&iter))
-        {
-          /* end iterator */
-          count += count_toggles_at_iter (&iter, of_tag);
-          break;
-        }
-    }
-  while (gtk_text_iter_compare (&iter, end) <= 0);
-  
-  return count;
-}
-
-static gint
-count_toggles_in_buffer (GtkTextBuffer *buffer,
-                         GtkTextTag    *of_tag)
-{
-  GtkTextIter start, end;
-
-  gtk_text_buffer_get_bounds (buffer, &start, &end);
-
-  return count_toggles_in_range_by_char (buffer, of_tag, &start, &end);
-}
-
-static void
-check_specific_tag_in_range (GtkTextBuffer     *buffer,
-                             const gchar       *tag_name,
-                             const GtkTextIter *start,
-                             const GtkTextIter *end)
-{
-  GtkTextIter iter;
-  GtkTextTag *tag;
-  gboolean state;
-  gint count;
-  gint buffer_count;
-  gint last_offset;
-
-  if (gtk_text_iter_compare (start, end) > 0)
-    {
-      g_print ("  (inverted range for checking tags, skipping)\n");
-      return;
-    }
-  
-  tag = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer),
-                                   tag_name);
-
-  buffer_count = count_toggles_in_range_by_char (buffer, tag, start, end);
-  
-  state = FALSE;
-  count = 0;
-
-  last_offset = -1;
-  iter = *start;
-  if (gtk_text_iter_toggles_tag (&iter, tag) ||
-      gtk_text_iter_forward_to_tag_toggle (&iter, tag))
-    {
-      do
-        {
-          gint this_offset;
-          
-          ++count;
-
-          this_offset = gtk_text_iter_get_offset (&iter);
-
-          if (this_offset <= last_offset)
-            g_error ("forward_to_tag_toggle moved in wrong direction");
-
-          last_offset = this_offset;
-          
-          if (gtk_text_iter_begins_tag (&iter, tag))
-            {
-              if (state)
-                g_error ("Tag %p is already on, and was toggled on?", tag);
-              state = TRUE;
-            }          
-          else if (gtk_text_iter_ends_tag (&iter, tag))
-            {
-              if (!state)
-                g_error ("Tag %p toggled off, but wasn't toggled on?", tag);
-              state = FALSE;
-            }
-          else
-            g_error ("forward_to_tag_toggle went to a location without a toggle");
-        }
-      while (gtk_text_iter_forward_to_tag_toggle (&iter, tag) &&
-             gtk_text_iter_compare (&iter, end) <= 0);
-    }
-
-  if (count != buffer_count)
-    g_error ("Counted %d tags iterating by char, %d iterating forward by tag toggle\n",
-             buffer_count, count);
-  
-  state = FALSE;
-  count = 0;
-  
-  iter = *end;
-  last_offset = gtk_text_iter_get_offset (&iter);
-  if (gtk_text_iter_toggles_tag (&iter, tag) ||
-      gtk_text_iter_backward_to_tag_toggle (&iter, tag))
-    {
-      do
-        {
-          gint this_offset;
-          
-          ++count;
-
-          this_offset = gtk_text_iter_get_offset (&iter);
-          
-          if (this_offset >= last_offset)
-            g_error ("backward_to_tag_toggle moved in wrong direction");
-          
-          last_offset = this_offset;
-
-          if (gtk_text_iter_begins_tag (&iter, tag))
-            {
-              if (!state)
-                g_error ("Tag %p wasn't on when we got to the on toggle going backward?", tag);
-              state = FALSE;
-            }
-          else if (gtk_text_iter_ends_tag (&iter, tag))
-            {
-              if (state)
-                g_error ("Tag %p off toggle, but we were already inside a tag?", tag);
-              state = TRUE;
-            }
-          else
-            g_error ("backward_to_tag_toggle went to a location without a toggle");
-        }
-      while (gtk_text_iter_backward_to_tag_toggle (&iter, tag) &&
-             gtk_text_iter_compare (&iter, start) >= 0);
-    }
-
-  if (count != buffer_count)
-    g_error ("Counted %d tags iterating by char, %d iterating backward by tag toggle\n",
-             buffer_count, count);
-}
-
-static void
-check_specific_tag (GtkTextBuffer *buffer,
-                    const gchar   *tag_name)
-{
-  GtkTextIter start, end;
-
-  gtk_text_buffer_get_bounds (buffer, &start, &end);
-  check_specific_tag_in_range (buffer, tag_name, &start, &end);
-  gtk_text_iter_forward_chars (&start, 2);
-  gtk_text_iter_backward_chars (&end, 2);
-  if (gtk_text_iter_compare (&start, &end) < 0)
-    check_specific_tag_in_range (buffer, tag_name, &start, &end);
-}
-
-static void
-run_tests (GtkTextBuffer *buffer)
-{
-  GtkTextIter iter;
-  GtkTextIter start;
-  GtkTextIter end;
-  GtkTextIter mark;
-  gint i, j;
-  gint num_chars;
-  GtkTextMark *bar_mark;
-  GtkTextTag *tag;
-  GHashTable *tag_states;
-  gint count;
-  gint buffer_count;
-  
-  gtk_text_buffer_get_bounds (buffer, &start, &end);
-
-  /* Check that walking the tree via chars and via iterators produces
-   * the same number of indexable locations.
-   */
-  num_chars = gtk_text_buffer_get_char_count (buffer);
-  iter = start;
-  bar_mark = gtk_text_buffer_create_mark (buffer, "bar", &iter, FALSE);
-  i = 0;
-  while (i < num_chars)
-    {
-      GtkTextIter current;
-      GtkTextMark *foo_mark;
-
-      gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
-
-      if (!gtk_text_iter_equal (&iter, &current))
-        {
-          g_error ("get_char_index didn't return current iter");
-        }
-
-      j = gtk_text_iter_get_offset (&iter);
-
-      if (i != j)
-        {
-          g_error ("iter converted to %d not %d", j, i);
-        }
-
-      /* get/set mark */
-      gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
-
-      if (!gtk_text_iter_equal (&iter, &mark))
-        {
-          gtk_text_iter_spew (&iter, "iter");
-          gtk_text_iter_spew (&mark, "mark");
-          g_error ("Mark not moved to the right place.");
-        }
-
-      foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
-      gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
-      gtk_text_buffer_delete_mark (buffer, foo_mark);
-
-      if (!gtk_text_iter_equal (&iter, &mark))
-        {
-          gtk_text_iter_spew (&iter, "iter");
-          gtk_text_iter_spew (&mark, "mark");
-          g_error ("Mark not created in the right place.");
-        }
-
-      if (gtk_text_iter_is_end (&iter))
-        g_error ("iterators ran out before chars (offset %d of %d)",
-                 i, num_chars);
-
-      gtk_text_iter_forward_char (&iter);
-
-      gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
-
-      ++i;
-    }
-
-  if (!gtk_text_iter_equal (&iter, &end))
-    g_error ("Iterating over all chars didn't end with the end iter");
-
-  /* Do the tree-walk backward
-   */
-  num_chars = gtk_text_buffer_get_char_count (buffer);
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1);
-
-  gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
-
-  i = num_chars;
-
-  if (!gtk_text_iter_equal (&iter, &end))
-    g_error ("iter at char -1 is not equal to the end iterator");
-
-  while (i >= 0)
-    {
-      GtkTextIter current;
-      GtkTextMark *foo_mark;
-
-      gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
-
-      if (!gtk_text_iter_equal (&iter, &current))
-        {
-          g_error ("get_char_index didn't return current iter while going backward");
-        }
-      j = gtk_text_iter_get_offset (&iter);
-
-      if (i != j)
-        {
-          g_error ("going backward, iter converted to %d not %d", j, i);
-        }
-
-      /* get/set mark */
-      gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
-
-      if (!gtk_text_iter_equal (&iter, &mark))
-        {
-          gtk_text_iter_spew (&iter, "iter");
-          gtk_text_iter_spew (&mark, "mark");
-          g_error ("Mark not moved to the right place.");
-        }
-
-      foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
-      gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
-      gtk_text_buffer_delete_mark (buffer, foo_mark);
-
-      if (!gtk_text_iter_equal (&iter, &mark))
-        {
-          gtk_text_iter_spew (&iter, "iter");
-          gtk_text_iter_spew (&mark, "mark");
-          g_error ("Mark not created in the right place.");
-        }
-
-      if (i > 0)
-        {
-          if (!gtk_text_iter_backward_char (&iter))
-            g_error ("iterators ran out before char indexes");
-
-          gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
-        }
-      else
-        {
-          if (gtk_text_iter_backward_char (&iter))
-            g_error ("went backward from 0?");
-        }
-
-      --i;
-    }
-
-  if (!gtk_text_iter_equal (&iter, &start))
-    g_error ("Iterating backward over all chars didn't end with the start iter");
-
-  /*
-   * Check that get_line_count returns the same number of lines
-   * as walking the tree by line
-   */
-  i = 1; /* include current (first) line */
-  gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
-  while (gtk_text_iter_forward_line (&iter))
-    ++i;
-
-  if (i != gtk_text_buffer_get_line_count (buffer))
-    g_error ("Counted %d lines, buffer has %d", i,
-             gtk_text_buffer_get_line_count (buffer));
-
-  /*
-   * Check that moving over tag toggles thinks about working.
-   */
-
-  buffer_count = count_toggles_in_buffer (buffer, NULL);
-  
-  tag_states = g_hash_table_new (NULL, NULL);
-  count = 0;
-  
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
-  if (gtk_text_iter_toggles_tag (&iter, NULL) ||
-      gtk_text_iter_forward_to_tag_toggle (&iter, NULL))
-    {
-      do
-        {
-          GSList *tags;
-          GSList *tmp;
-          gboolean found_some = FALSE;
-          
-          /* get toggled-on tags */
-          tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
-
-          if (tags)
-            found_some = TRUE;
-          
-          tmp = tags;
-          while (tmp != NULL)
-            {
-              ++count;
-              
-              tag = tmp->data;
-              
-              if (g_hash_table_lookup (tag_states, tag))
-                g_error ("Tag %p is already on, and was toggled on?", tag);
-
-              g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
-          
-              tmp = g_slist_next (tmp);
-            }
-
-          g_slist_free (tags);
-      
-          /* get toggled-off tags */
-          tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
-
-          if (tags)
-            found_some = TRUE;
-          
-          tmp = tags;
-          while (tmp != NULL)
-            {
-              ++count;
-              
-              tag = tmp->data;
-
-              if (!g_hash_table_lookup (tag_states, tag))
-                g_error ("Tag %p is already off, and was toggled off?", tag);
-
-              g_hash_table_remove (tag_states, tag);
-          
-              tmp = g_slist_next (tmp);
-            }
-
-          g_slist_free (tags);
-
-          if (!found_some)
-            g_error ("No tags found going forward to tag toggle.");
-
-        }
-      while (gtk_text_iter_forward_to_tag_toggle (&iter, NULL));
-    }
-  
-  g_hash_table_destroy (tag_states);
-
-  if (count != buffer_count)
-    g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
-             buffer_count, count);
-  
-  /* Go backward; here TRUE in the hash means we saw
-   * an off toggle last.
-   */
-  
-  tag_states = g_hash_table_new (NULL, NULL);
-  count = 0;
-  
-  gtk_text_buffer_get_end_iter (buffer, &iter);
-  if (gtk_text_iter_toggles_tag (&iter, NULL) ||
-      gtk_text_iter_backward_to_tag_toggle (&iter, NULL))
-    {
-      do
-        {
-          GSList *tags;
-          GSList *tmp;
-          gboolean found_some = FALSE;
-          
-          /* get toggled-off tags */
-          tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
-
-          if (tags)
-            found_some = TRUE;
-          
-          tmp = tags;
-          while (tmp != NULL)
-            {
-              ++count;
-              
-              tag = tmp->data;
-
-              if (g_hash_table_lookup (tag_states, tag))
-                g_error ("Tag %p has two off-toggles in a row?", tag);
-          
-              g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
-          
-              tmp = g_slist_next (tmp);
-            }
-
-          g_slist_free (tags);
-      
-          /* get toggled-on tags */
-          tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
-
-          if (tags)
-            found_some = TRUE;
-          
-          tmp = tags;
-          while (tmp != NULL)
-            {
-              ++count;
-              
-              tag = tmp->data;
-
-              if (!g_hash_table_lookup (tag_states, tag))
-                g_error ("Tag %p was toggled on, but saw no off-toggle?", tag);
-
-              g_hash_table_remove (tag_states, tag);
-          
-              tmp = g_slist_next (tmp);
-            }
-
-          g_slist_free (tags);
-
-          if (!found_some)
-            g_error ("No tags found going backward to tag toggle.");
-        }
-      while (gtk_text_iter_backward_to_tag_toggle (&iter, NULL));
-    }
-  
-  g_hash_table_destroy (tag_states);
-
-  if (count != buffer_count)
-    g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
-             buffer_count, count);
-
-  check_specific_tag (buffer, "fg_red");
-  check_specific_tag (buffer, "bg_green");
-  check_specific_tag (buffer, "front_tag");
-  check_specific_tag (buffer, "center_tag");
-  check_specific_tag (buffer, "end_tag");
-}
-
-
-static const char  *book_closed_xpm[] = {
-"16 16 6 1",
-"       c None s None",
-".      c black",
-"X      c red",
-"o      c yellow",
-"O      c #808080",
-"#      c white",
-"                ",
-"       ..       ",
-"     ..XX.      ",
-"   ..XXXXX.     ",
-" ..XXXXXXXX.    ",
-".ooXXXXXXXXX.   ",
-"..ooXXXXXXXXX.  ",
-".X.ooXXXXXXXXX. ",
-".XX.ooXXXXXX..  ",
-" .XX.ooXXX..#O  ",
-"  .XX.oo..##OO. ",
-"   .XX..##OO..  ",
-"    .X.#OO..    ",
-"     ..O..      ",
-"      ..        ",
-"                "};
-
-static void
-fill_buffer (GtkTextBuffer *buffer)
-{
-  GtkTextTag *tag;
-  GdkColor color, color2;
-  GtkTextIter iter;
-  GtkTextIter iter2;
-  GdkPixbuf *pixbuf;
-  int i;
-
-  color.red = color.green = 0;
-  color.blue = 0xffff;
-  color2.red = 0xfff;
-  color2.blue = 0x0;
-  color2.green = 0;
-  
-  gtk_text_buffer_create_tag (buffer, "fg_blue",
-                              "foreground_gdk", &color,
-                              "background_gdk", &color2,
-                              "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
-                              NULL);
-
-  color.blue = color.green = 0;
-  color.red = 0xffff;
-  
-  gtk_text_buffer_create_tag (buffer, "fg_red",
-                              "rise", -4,
-                              "foreground_gdk", &color,
-                              NULL);
-
-  color.blue = color.red = 0;
-  color.green = 0xffff;
-  
-  gtk_text_buffer_create_tag (buffer, "bg_green",
-                              "background_gdk", &color,
-                              "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
-                              NULL);
-
-  pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
-
-  g_assert (pixbuf != NULL);
-
-  i = 0;
-  while (i < 10)
-    {
-      gchar *str;
-
-      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
-
-      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
-
-      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
-
-      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
-
-      str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
-                            i);
-
-      gtk_text_buffer_insert (buffer, &iter, str, -1);
-
-      g_free (str);
-
-      gtk_text_buffer_insert (buffer, &iter,
-                              "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line\n\n"
-                              /* This is UTF8 stuff, Emacs doesn't
-                                 really know how to display it */
-                              "Spanish (Espa\303\261ol) \302\241Hola! / French (Fran\303\247ais) Bonjour, Salut / German (Deutsch S\303\274d) Gr\303\274\303\237 Gott (testing Latin-1 chars encoded in UTF8)\nThai (we can't display this, just making sure we don't crash)  (\340\270\240\340\270\262\340\270\251\340\270\262\340\271\204\340\270\227\340\270\242)  \340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\270\243\340\270\261\340\270\232, \340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\271\210\340\270\260\n",
-                              -1);
-
-      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
-      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
-
-      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
-
-      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
-
-      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
-
-      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
-
-      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
-
-      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
-
-      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
-      iter2 = iter;
-      gtk_text_iter_forward_chars (&iter2, 10);
-
-      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
-
-      gtk_text_iter_forward_chars (&iter, 7);
-      gtk_text_iter_forward_chars (&iter2, 10);
-
-      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
-
-      gtk_text_iter_forward_chars (&iter, 12);
-      gtk_text_iter_forward_chars (&iter2, 10);
-
-      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
-
-      gtk_text_iter_forward_chars (&iter, 10);
-      gtk_text_iter_forward_chars (&iter2, 15);
-
-      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
-
-      gtk_text_iter_forward_chars (&iter, 20);
-      gtk_text_iter_forward_chars (&iter2, 20);
-
-      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
-
-      gtk_text_iter_backward_chars (&iter, 25);
-      gtk_text_iter_forward_chars (&iter2, 5);
-
-      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
-
-      gtk_text_iter_forward_chars (&iter, 15);
-      gtk_text_iter_backward_chars (&iter2, 10);
-
-      gtk_text_buffer_remove_tag_by_name (buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_remove_tag_by_name (buffer, "fg_blue", &iter, &iter2);
-
-      ++i;
-    }
-
-  /* Put in tags that are just at the beginning, and just near the end,
-   * and just near the middle.
-   */
-  tag = gtk_text_buffer_create_tag (buffer, "front_tag", NULL);
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3);
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter2, 300);
-
-  gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);  
-  
-  tag = gtk_text_buffer_create_tag (buffer, "end_tag", NULL);
-  gtk_text_buffer_get_end_iter (buffer, &iter2);
-  gtk_text_iter_backward_chars (&iter2, 12);
-  iter = iter2;
-  gtk_text_iter_backward_chars (&iter, 157);
-
-  gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
-  
-  tag = gtk_text_buffer_create_tag (buffer, "center_tag", NULL);
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter,
-                                      gtk_text_buffer_get_char_count (buffer)/2);
-  gtk_text_iter_backward_chars (&iter, 37);
-  iter2 = iter;
-  gtk_text_iter_forward_chars (&iter2, 57);
-
-  gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);  
-
-  g_object_unref (pixbuf);
-}
-
-
-/*
- * Line separator tests (initially to avoid regression on bugzilla #57428)
- */
-
-static void
-test_line_separation (const char* str,
-                      gboolean    expect_next_line,
-                      gboolean    expect_end_iter,
-                      int         expected_line_count,
-                      int         expected_line_break,
-                      int         expected_next_line_start)
-{
-  GtkTextIter iter;
-  GtkTextBuffer* buffer;
-  gboolean on_next_line;
-  gboolean on_end_iter;
-  gint new_pos;
-
-  buffer = gtk_text_buffer_new (NULL);
-
-  gtk_text_buffer_set_text (buffer, str, -1);
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, expected_line_break);
-
-  g_assert (gtk_text_iter_ends_line (&iter) || gtk_text_iter_is_end (&iter));
-
-  g_assert (gtk_text_buffer_get_line_count (buffer) == expected_line_count);
-  
-  on_next_line = gtk_text_iter_forward_line (&iter);
-
-  g_assert (expect_next_line == on_next_line);
-
-  on_end_iter = gtk_text_iter_is_end (&iter);
-
-  g_assert (on_end_iter == expect_end_iter);
-  
-  new_pos = gtk_text_iter_get_offset (&iter);
-    
-  if (on_next_line)
-    g_assert (expected_next_line_start == new_pos);
-
-  ++expected_line_break;
-  while (expected_line_break < expected_next_line_start)
-    {
-      gtk_text_buffer_get_iter_at_offset (buffer, &iter, expected_line_break);
-
-      g_assert (!gtk_text_iter_ends_line (&iter));
-
-      on_next_line = gtk_text_iter_forward_line (&iter);
-        
-      g_assert (expect_next_line == on_next_line);
-        
-      new_pos = gtk_text_iter_get_offset (&iter);
-        
-      if (on_next_line)
-        g_assert (expected_next_line_start == new_pos);
-        
-      ++expected_line_break;
-    }
-
-  /* FIXME tests for backward line */
-  
-  g_object_unref (buffer);
-}
-
-/* there are cases where \r and \n should not be treated like \r\n,
- * originally bug #337022. */
-static void
-split_r_n_separators_test (void)
-{
-  GtkTextBuffer *buffer;
-  GtkTextIter iter;
-
-  buffer = gtk_text_buffer_new (NULL);
-
-  gtk_text_buffer_set_text (buffer, "foo\ra\nbar\n", -1);
-
-  /* delete 'a' so that we have
-
-     1 foo\r
-     2 \n
-     3 bar\n
-
-   * and both \r and \n are line separators */
-
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 5);
-  gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
-
-  g_assert (gtk_text_iter_ends_line (&iter));
-
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3);
-  g_assert (gtk_text_iter_ends_line (&iter));
-
-  g_object_unref (buffer);
-}
-
-static void
-test_line_separator (void)
-{
-  char *str;
-  char buf[7] = { '\0', };
-
-  /* Only one character has type G_UNICODE_PARAGRAPH_SEPARATOR in
-   * Unicode 3.0; update this if that changes.
-   */
-#define PARAGRAPH_SEPARATOR 0x2029
-  
-  test_line_separation ("line", FALSE, TRUE, 1, 4, 4);
-  test_line_separation ("line\r\n", FALSE, TRUE, 2, 4, 6);
-  test_line_separation ("line\r", FALSE, TRUE, 2, 4, 5);
-  test_line_separation ("line\n", FALSE, TRUE, 2, 4, 5);
-  test_line_separation ("line\rqw", TRUE, FALSE, 2, 4, 5);
-  test_line_separation ("line\nqw", TRUE, FALSE, 2, 4, 5);
-  test_line_separation ("line\r\nqw", TRUE, FALSE, 2, 4, 6);
-  
-  g_unichar_to_utf8 (PARAGRAPH_SEPARATOR, buf);
-  
-  str = g_strdup_printf ("line%s", buf);
-  test_line_separation (str, FALSE, TRUE, 2, 4, 5);
-  g_free (str);
-  str = g_strdup_printf ("line%sqw", buf);
-  test_line_separation (str, TRUE, FALSE, 2, 4, 5);
-  g_free (str);
-
-  split_r_n_separators_test ();
-}
-
-static void
-test_backspace (void)
-{
-  GtkTextBuffer *buffer;
-  GtkTextIter iter;
-  gboolean ret;
-
-  buffer = gtk_text_buffer_new (NULL);
-
-  gtk_text_buffer_set_text (buffer, "foo", -1);
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 2);
-  ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
-  g_assert (ret);
-  g_assert_cmpint (1, ==, gtk_text_iter_get_offset (&iter));
-  g_assert_cmpint (2, ==, gtk_text_buffer_get_char_count (buffer));
-
-  gtk_text_buffer_set_text (buffer, "foo", -1);
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
-  ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
-  g_assert (!ret);
-  g_assert_cmpint (0, ==, gtk_text_iter_get_offset (&iter));
-  g_assert_cmpint (3, ==, gtk_text_buffer_get_char_count (buffer));
-
-  /* test bug #544724 */
-  gtk_text_buffer_set_text (buffer, "foo\r\n\r\nbar", -1);
-  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 5);
-  ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
-  g_assert (ret);
-  g_assert_cmpint (0, ==, gtk_text_iter_get_line (&iter));
-  g_assert_cmpint (8, ==, gtk_text_buffer_get_char_count (buffer));
-
-  g_object_unref (buffer);
-}
-
-static void
-test_logical_motion (void)
-{
-  char *str;
-  char buf1[7] = { '\0', };
-  char buf2[7] = { '\0', };
-  char buf3[7] = { '\0', };
-  int expected[30];
-  int expected_steps;
-  int i;
-  GtkTextBuffer *buffer;
-  GtkTextIter iter;
-  
-  buffer = gtk_text_buffer_new (NULL);
-  
-#define LEADING_JAMO 0x1111
-#define VOWEL_JAMO 0x1167
-#define TRAILING_JAMO 0x11B9
-  
-  g_unichar_to_utf8 (LEADING_JAMO, buf1);
-  g_unichar_to_utf8 (VOWEL_JAMO, buf2);
-  g_unichar_to_utf8 (TRAILING_JAMO, buf3);
-
-  /* Build the string "abc<leading><vowel><trailing>def\r\nxyz" */
-  str = g_strconcat ("abc", buf1, buf2, buf3, "def\r\nxyz", NULL);
-  gtk_text_buffer_set_text (buffer, str, -1);
-  g_free (str);
-  
-  /* Check cursor positions */
-  memset (expected, 0, sizeof (expected));
-  expected[0] = 0;    /* before 'a' */
-  expected[1] = 1;    /* before 'b' */
-  expected[2] = 2;    /* before 'c' */
-  expected[3] = 3;    /* before jamo */
-  expected[4] = 6;    /* before 'd' */
-  expected[5] = 7;    /* before 'e' */
-  expected[6] = 8;    /* before 'f' */
-  expected[7] = 9;    /* before '\r' */
-  expected[8] = 11;   /* before 'x' */
-  expected[9] = 12;   /* before 'y' */
-  expected[10] = 13;  /* before 'z' */
-  expected[11] = 14;  /* after 'z' (only matters going backward) */
-  expected_steps = 11;
-  
-  gtk_text_buffer_get_start_iter (buffer, &iter);
-  i = 0;
-  do
-    {
-      int pos;
-
-      pos = gtk_text_iter_get_offset (&iter);
-      
-      if (pos != expected[i])
-        {
-          g_error ("Cursor position %d, expected %d",
-                   pos, expected[i]);
-        }
-
-      ++i;      
-    }
-  while (gtk_text_iter_forward_cursor_position (&iter));
-
-  if (!gtk_text_iter_is_end (&iter))
-    g_error ("Expected to stop at the end iterator\n");
-
-  if (!gtk_text_iter_is_cursor_position (&iter))
-    g_error ("Should be a cursor position before the end iterator");
-  
-  if (i != expected_steps)
-    g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
-
-  i = expected_steps;
-  do
-    {
-      int pos;
-
-      pos = gtk_text_iter_get_offset (&iter);
-      
-      if (pos != expected[i])
-        {
-          g_error ("Moving backward, cursor position %d, expected %d",
-                   pos, expected[i]);
-        }
-
-      /* g_print ("%d = %d\n", pos, expected[i]); */
-      
-      --i;
-    }
-  while (gtk_text_iter_backward_cursor_position (&iter));
-
-  if (i != -1)
-    g_error ("Expected %d steps, there were actually %d\n", expected_steps - i, i);
-
-  if (!gtk_text_iter_is_start (&iter))
-    g_error ("Expected to stop at the start iterator\n");
-
-
-  /* Check sentence boundaries */
-  
-  gtk_text_buffer_set_text (buffer, "Hi.\nHi. \nHi! Hi. Hi? Hi.", -1);
-
-  memset (expected, 0, sizeof (expected));
-
-  expected[0] = 0;    /* before first Hi */
-  expected[1] = 3;    /* After first . */
-  expected[2] = 7;    /* After second . */
-  expected[3] = 12;   /* After ! */
-  expected[4] = 16;   /* After third . */
-  expected[5] = 20;   /* After ? */
-  
-  expected_steps = 6;
-  
-  gtk_text_buffer_get_start_iter (buffer, &iter);
-  i = 0;
-  do
-    {
-      int pos;
-
-      pos = gtk_text_iter_get_offset (&iter);
-
-      if (pos != expected[i])
-        {
-          g_error ("Sentence position %d, expected %d",
-                   pos, expected[i]);
-        }
-
-      if (i != 0 &&
-          !gtk_text_iter_is_end (&iter) &&
-          !gtk_text_iter_ends_sentence (&iter))
-        g_error ("Iterator at %d should end a sentence", pos);
-      
-      ++i;
-    }
-  while (gtk_text_iter_forward_sentence_end (&iter));
-
-  if (i != expected_steps)
-    g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
-
-  if (!gtk_text_iter_is_end (&iter))
-    g_error ("Expected to stop at the end iterator\n");
-  
-  gtk_text_buffer_set_text (buffer, "Hi.\nHi. \nHi! Hi. Hi? Hi.", -1);
-
-  memset (expected, 0, sizeof (expected));
-
-  expected[0] = 24;
-  expected[1] = 21;
-  expected[2] = 17;
-  expected[3] = 13;
-  expected[4] = 9;
-  expected[5] = 4;
-  expected[6] = 0;
-  
-  expected_steps = 7;
-  
-  gtk_text_buffer_get_end_iter (buffer, &iter);
-  i = 0;
-  do
-    {
-      int pos;
-
-      pos = gtk_text_iter_get_offset (&iter);
-
-      if (pos != expected[i])
-        {
-          g_error ("Sentence position %d, expected %d",
-                   pos, expected[i]);
-        }
-
-      if (pos != 0 &&
-          !gtk_text_iter_is_end (&iter) &&
-          !gtk_text_iter_starts_sentence (&iter))
-        g_error ("Iterator at %d should start a sentence", pos);
-      
-      ++i;
-    }
-  while (gtk_text_iter_backward_sentence_start (&iter));
-
-  if (i != expected_steps)
-    g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
-
-  if (gtk_text_iter_get_offset (&iter) != 0)
-    g_error ("Expected to stop at the start iterator\n");
-  
-  g_object_unref (buffer);
-}
-
-static void
-test_marks (void)
-{
-  GtkTextBuffer *buf1, *buf2;
-  GtkTextMark *mark;
-  GtkTextIter iter;
-
-  buf1 = gtk_text_buffer_new (NULL);
-  buf2 = gtk_text_buffer_new (NULL);
-
-  gtk_text_buffer_get_start_iter (buf1, &iter);
-  mark = gtk_text_buffer_create_mark (buf1, "foo", &iter, TRUE);
-  g_object_ref (mark);
-  gtk_text_mark_set_visible (mark, TRUE);
-  gtk_text_buffer_delete_mark (buf1, mark);
-
-  g_assert (gtk_text_mark_get_visible (mark));
-  g_assert (gtk_text_mark_get_left_gravity (mark));
-  g_assert (!strcmp ("foo", gtk_text_mark_get_name (mark)));
-  g_assert (gtk_text_mark_get_buffer (mark) == NULL);
-  g_assert (gtk_text_mark_get_deleted (mark));
-  g_assert (gtk_text_buffer_get_mark (buf1, "foo") == NULL);
-
-  gtk_text_buffer_get_start_iter (buf2, &iter);
-  gtk_text_buffer_add_mark (buf2, mark, &iter);
-  gtk_text_buffer_insert (buf2, &iter, "ewfwefwefwe", -1);
-  gtk_text_buffer_get_iter_at_mark (buf2, &iter, mark);
-
-  g_assert (gtk_text_mark_get_visible (mark));
-  g_assert (gtk_text_iter_is_start (&iter));
-  g_assert (gtk_text_mark_get_left_gravity (mark));
-  g_assert (!strcmp ("foo", gtk_text_mark_get_name (mark)));
-  g_assert (gtk_text_mark_get_buffer (mark) == buf2);
-  g_assert (!gtk_text_mark_get_deleted (mark));
-  g_assert (gtk_text_buffer_get_mark (buf2, "foo") == mark);
-
-  gtk_text_buffer_delete_mark (buf2, mark);
-  gtk_text_mark_set_visible (mark, FALSE);
-  g_object_unref (mark);
-
-  mark = gtk_text_mark_new ("blah", TRUE);
-  gtk_text_buffer_get_start_iter (buf1, &iter);
-  gtk_text_mark_set_visible (mark, TRUE);
-  gtk_text_buffer_add_mark (buf1, mark, &iter);
-
-  g_assert (gtk_text_mark_get_visible (mark));
-  g_assert (gtk_text_mark_get_buffer (mark) == buf1);
-  g_assert (!gtk_text_mark_get_deleted (mark));
-  g_assert (gtk_text_buffer_get_mark (buf1, "blah") == mark);
-  g_assert (!strcmp ("blah", gtk_text_mark_get_name (mark)));
-
-  gtk_text_mark_set_visible (mark, FALSE);
-  gtk_text_buffer_delete_mark (buf1, mark);
-  g_assert (!gtk_text_mark_get_visible (mark));
-  g_assert (gtk_text_buffer_get_mark (buf1, "blah") == NULL);
-  g_assert (gtk_text_mark_get_buffer (mark) == NULL);
-  g_assert (gtk_text_mark_get_deleted (mark));
-
-  gtk_text_buffer_get_start_iter (buf2, &iter);
-  gtk_text_buffer_add_mark (buf2, mark, &iter);
-  g_assert (gtk_text_mark_get_buffer (mark) == buf2);
-  g_assert (!gtk_text_mark_get_deleted (mark));
-  g_assert (gtk_text_buffer_get_mark (buf2, "blah") == mark);
-  g_assert (!strcmp ("blah", gtk_text_mark_get_name (mark)));
-
-  g_object_unref (mark);
-  g_object_unref (buf1);
-  g_object_unref (buf2);
-}
-
-static void
-test_utf8 (void)
-{
-  gunichar ch;
-
-  /* Check UTF8 unknown char thing */
-  g_assert (GTK_TEXT_UNKNOWN_CHAR_UTF8_LEN == 3);
-  g_assert (g_utf8_strlen (gtk_text_unknown_char_utf8_gtk_tests_only (), 3) == 1);
-  ch = g_utf8_get_char (gtk_text_unknown_char_utf8_gtk_tests_only ());
-  g_assert (ch == GTK_TEXT_UNKNOWN_CHAR);
-}
-
-static void
-test_empty_buffer (void)
-{
-  GtkTextBuffer *buffer;
-  int n;
-  GtkTextIter start;
-
-  buffer = gtk_text_buffer_new (NULL);
-
-  /* Check that buffer starts with one empty line and zero chars */
-  n = gtk_text_buffer_get_line_count (buffer);
-  if (n != 1)
-    g_error ("%d lines, expected 1", n);
-
-  n = gtk_text_buffer_get_char_count (buffer);
-  if (n != 0)
-    g_error ("%d chars, expected 0", n);
-
-  /* empty first line contains 0 chars */
-  gtk_text_buffer_get_start_iter (buffer, &start);
-  n = gtk_text_iter_get_chars_in_line (&start);
-  if (n != 0)
-    g_error ("%d chars in first line, expected 0", n);
-  n = gtk_text_iter_get_bytes_in_line (&start);
-  if (n != 0)
-    g_error ("%d bytes in first line, expected 0", n);
-  
-  /* Run gruesome alien test suite on buffer */
-  run_tests (buffer);
-
-  g_object_unref (buffer);
-}
-
-static void
-test_get_set(void)
-{
-  GtkTextBuffer *buffer;
-
-  buffer = gtk_text_buffer_new (NULL);
-
-  check_get_set_text (buffer, "Hello");
-  check_get_set_text (buffer, "Hello\n");
-  check_get_set_text (buffer, "Hello\r\n");
-  check_get_set_text (buffer, "Hello\r");
-  check_get_set_text (buffer, "Hello\nBar\nFoo");
-  check_get_set_text (buffer, "Hello\nBar\nFoo\n");
-
-  g_object_unref (buffer);
-}
-
-static void
-test_fill_empty (void)
-{
-  GtkTextBuffer *buffer;
-  int n;
-  GtkTextIter start, end;
-  
-  buffer = gtk_text_buffer_new (NULL);
-
-  /* Put stuff in the buffer */
-  fill_buffer (buffer);
-
-  /* Subject stuff-bloated buffer to further torment */
-  run_tests (buffer);
-
-  /* Delete all stuff from the buffer */
-  gtk_text_buffer_get_bounds (buffer, &start, &end);
-  gtk_text_buffer_delete (buffer, &start, &end);
-
-  /* Check buffer for emptiness (note that a single
-     empty line always remains in the buffer) */
-  n = gtk_text_buffer_get_line_count (buffer);
-  if (n != 1)
-    g_error ("%d lines, expected 1", n);
-
-  n = gtk_text_buffer_get_char_count (buffer);
-  if (n != 0)
-    g_error ("%d chars, expected 0", n);
-
-  run_tests (buffer);
-
-  g_object_unref (buffer);
-}
-
-static void
-test_tag (void)
-{
-  GtkTextBuffer *buffer;
-  GtkTextIter start, end;
-  
-  buffer = gtk_text_buffer_new (NULL);
-
-  fill_buffer (buffer);
-
-  gtk_text_buffer_set_text (buffer, "adcdef", -1);
-  gtk_text_buffer_get_iter_at_offset (buffer, &start, 1);
-  gtk_text_buffer_get_iter_at_offset (buffer, &end, 3);
-  gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &start, &end);
-  
-  run_tests (buffer);
-  
-  g_object_unref (buffer);
-}
-
-int
-main (int argc, char** argv)
-{
-  /* First, we turn on btree debugging. */
-  gtk_set_debug_flags (gtk_get_debug_flags () | GTK_DEBUG_TEXT);
-
-  gtk_test_init (&argc, &argv);
-
-  g_test_add_func ("/TextBuffer/UTF8 unknown char", test_utf8);
-  g_test_add_func ("/TextBuffer/Line separator", test_line_separator);
-  g_test_add_func ("/TextBuffer/Backspace", test_backspace);
-  g_test_add_func ("/TextBuffer/Logical motion", test_logical_motion);
-  g_test_add_func ("/TextBuffer/Marks", test_marks);
-  g_test_add_func ("/TextBuffer/Empty buffer", test_empty_buffer);
-  g_test_add_func ("/TextBuffer/Get and Set", test_get_set);
-  g_test_add_func ("/TextBuffer/Fill and Empty", test_fill_empty);
-  g_test_add_func ("/TextBuffer/Tag", test_tag);
-  
-  return g_test_run();
-}
diff --git a/gtk/tests/textiter.c b/gtk/tests/textiter.c
deleted file mode 100644 (file)
index bee33de..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-static void
-test_empty_search ()
-{
-  GtkTextBuffer *buffer;
-  GtkTextIter it, s, e;
-  gboolean res;
-
-  buffer = gtk_text_buffer_new (NULL);
-  gtk_text_buffer_set_text (buffer, "This is some foo text", -1);
-
-  /* search from start forward */
-  gtk_text_buffer_get_start_iter (buffer, &it);
-  res = gtk_text_iter_forward_search (&it, "", 0, &s, &e, NULL);
-  g_assert (res);
-  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e));
-  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 1);
-
-  /* search from end backward */
-  gtk_text_buffer_get_end_iter (buffer, &it);
-  res = gtk_text_iter_backward_search (&it, "", 0, &s, &e, NULL);
-  g_assert (res);
-  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e));
-  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 20);
-}
-
-static void
-check_found_forward (const gchar *haystack,
-                     const gchar *needle,
-                     GtkTextSearchFlags flags,
-                     int expected_start,
-                     int expected_end,
-                     const gchar *expected_string)
-{
-  GtkTextBuffer *buffer;
-  GtkTextIter i, s, e;
-  gboolean res;
-  gchar *text;
-
-  buffer = gtk_text_buffer_new (NULL);
-
-  gtk_text_buffer_set_text (buffer, haystack, -1);
-
-  /* TODO: add test with limit before, after and in the middle
-     of expected start and end */
-
-  /* search from start forward */
-  gtk_text_buffer_get_start_iter (buffer, &i);
-  res = gtk_text_iter_forward_search (&i, needle, flags, &s, &e, NULL);
-  g_assert (res);
-  g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s));
-  g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e));
-  text = gtk_text_iter_get_text (&s, &e);
-  g_assert_cmpstr (expected_string, ==, text);
-  g_free (text);
-
-  g_object_unref (buffer);
-}
-
-static void
-check_found_backward (const gchar *haystack,
-                      const gchar *needle,
-                      GtkTextSearchFlags flags,
-                      int expected_start,
-                      int expected_end,
-                      const gchar *expected_string)
-{
-  GtkTextBuffer *buffer;
-  GtkTextIter i, s, e;
-  gboolean res;
-  gchar *text;
-
-  buffer = gtk_text_buffer_new (NULL);
-
-  gtk_text_buffer_set_text (buffer, haystack, -1);
-
-  /* search from end backward */
-  gtk_text_buffer_get_end_iter (buffer, &i);
-  res = gtk_text_iter_backward_search (&i, needle, flags, &s, &e, NULL);
-  g_assert (res);
-  g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s));
-  g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e));
-  text = gtk_text_iter_get_text (&s, &e);
-  g_assert_cmpstr (expected_string, ==, text);
-  g_free (text);
-
-  g_object_unref (buffer);
-}
-
-static void
-check_not_found (const gchar *haystack,
-                 const gchar *needle,
-                 GtkTextSearchFlags flags)
-{
-  GtkTextBuffer *buffer;
-  GtkTextIter i, s, e;
-  gboolean res;
-
-  buffer = gtk_text_buffer_new (NULL);
-
-  gtk_text_buffer_set_text (buffer, haystack, -1);
-
-  /* search from start forward */
-  gtk_text_buffer_get_start_iter (buffer, &i);
-  res = gtk_text_iter_forward_search (&i, needle, flags, &s, &e, NULL);
-  g_assert (res == FALSE);
-
-  /* search from end backward */
-  gtk_text_buffer_get_end_iter (buffer, &i);
-  res = gtk_text_iter_backward_search (&i, needle, flags, &s, &e, NULL);
-  g_assert (res == FALSE);
-
-  g_object_unref (buffer);
-}
-
-static void
-test_full_buffer (void)
-{
-  check_found_forward ("foo", "foo", 0, 0, 3, "foo");
-  check_found_backward ("foo", "foo", 0, 0, 3, "foo");
-  check_found_forward ("foo", "foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
-  check_found_backward ("foo", "foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
-  check_found_forward ("foo", "Foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
-  check_found_backward ("foo", "Foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
-}
-
-static void
-test_search (void)
-{
-  /* simple match */
-  check_found_forward ("This is some foo text", "foo", 0, 13, 16, "foo");
-  check_found_backward ("This is some foo text", "foo", 0, 13, 16, "foo");
-  check_not_found ("This is some foo text", "Foo", 0);
-
-  /* different matches for forward and backward */
-  check_found_forward ("This is some foo foo text", "foo", 0, 13, 16, "foo");
-  check_found_backward ("This is some foo foo text", "foo", 0, 17, 20, "foo");
-
-  /* new lines in the haystack */
-  check_found_forward ("This is some\nfoo text", "foo", 0, 13, 16, "foo");
-  check_found_backward ("This is some\nfoo text", "foo", 0, 13, 16, "foo");
-  check_found_forward ("This is some foo\nfoo text", "foo", 0, 13, 16, "foo");
-  check_found_backward ("This is some foo\nfoo text", "foo", 0, 17, 20, "foo");
-  check_not_found ("This is some\nfoo text", "Foo", 0);
-
-  /* end of buffer */
-  check_found_forward ("This is some\ntext foo", "foo", 0, 18, 21, "foo");
-  check_found_backward ("This is some\ntext foo", "foo", 0, 18, 21, "foo");
-  check_not_found ("This is some\ntext foo", "Foo", 0);
-
-  /* multiple lines in the needle */
-  check_found_forward ("This is some foo\nfoo text", "foo\nfoo", 0, 13, 20, "foo\nfoo");
-  check_found_backward ("This is some foo\nfoo text", "foo\nfoo", 0, 13, 20, "foo\nfoo");
-  check_not_found ("This is some foo\nfoo text", "Foo\nfoo", 0);
-}
-
-static void
-test_search_caseless (void)
-{
-  GtkTextSearchFlags flags;
-
-  flags = GTK_TEXT_SEARCH_CASE_INSENSITIVE;
-
-  /* simple match */
-  check_found_forward ("This is some foo text", "foo", flags, 13, 16, "foo");
-  check_found_forward ("This is some foo text", "Foo", flags, 13, 16, "foo");
-  check_found_forward ("This is some Foo text", "foo", flags, 13, 16, "Foo");
-  check_found_backward ("This is some foo text", "foo", flags, 13, 16, "foo");
-  check_found_backward ("This is some foo text", "Foo", flags, 13, 16, "foo");
-  check_found_backward ("This is some Foo text", "foo", flags, 13, 16, "Foo");
-
-  /* check also that different composition of utf8 characters
-     (e.g. accented letters) match */
-
-  /* different matches for forward and backward */
-  check_found_forward ("This is some foo foo text", "foo", flags, 13, 16, "foo");
-  check_found_forward ("This is some foo foo text", "Foo", flags, 13, 16, "foo");
-  check_found_forward ("This is some Foo foo text", "foo", flags, 13, 16, "Foo");
-  check_found_forward ("This is some \303\200 \303\240 text", "\303\240", flags, 13, 14, "\303\200");
-  check_found_forward ("This is some \303\200 \303\240 text", "\303\200", flags, 13, 14, "\303\200");
-  check_found_forward ("This is some \303\200 \303\240 text", "a\314\200", flags, 13, 14, "\303\200");
-  check_found_backward ("This is some foo foo text", "foo", flags, 17, 20, "foo");
-  check_found_backward ("This is some foo foo text", "Foo", flags, 17, 20, "foo");
-  check_found_backward ("This is some foo Foo text", "foo", flags, 17, 20, "Foo");
-  check_found_backward ("This is some \303\200 \303\240 text", "\303\240", flags, 15, 16, "\303\240");
-  check_found_backward ("This is some \303\200 \303\240 text", "\303\200", flags, 15, 16, "\303\240");
-  check_found_backward ("This is some \303\200 \303\240 text", "a\314\200", flags, 15, 16, "\303\240");
-
-  /* new lines in the haystack */
-  check_found_forward ("This is some\nfoo text", "foo", flags, 13, 16, "foo");
-  check_found_forward ("This is some\nfoo text", "Foo", flags, 13, 16, "foo");
-  check_found_forward ("This is some\nFoo text", "foo", flags, 13, 16, "Foo");
-  check_found_forward ("This is some\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
-  check_found_forward ("This is some\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
-  check_found_backward ("This is some\nfoo text", "foo", flags, 13, 16, "foo");
-  check_found_backward ("This is some\nfoo text", "Foo", flags, 13, 16, "foo");
-  check_found_backward ("This is some\nFoo text", "foo", flags, 13, 16, "Foo");
-  check_found_backward ("This is some\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
-  check_found_backward ("This is some\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
-  check_found_forward ("This is some foo\nfoo text", "foo", flags, 13, 16, "foo");
-  check_found_forward ("This is some foo\nfoo text", "Foo", flags, 13, 16, "foo");
-  check_found_forward ("This is some Foo\nfoo text", "foo", flags, 13, 16, "Foo");
-  check_found_forward ("This is some \303\200\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
-  check_found_forward ("This is some \303\200\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
-  check_found_backward ("This is some foo\nfoo text", "foo", flags, 17, 20, "foo");
-  check_found_backward ("This is some foo\nfoo text", "Foo", flags, 17, 20, "foo");
-  check_found_backward ("This is some foo\nFoo text", "foo", flags, 17, 20, "Foo");
-  check_found_backward ("This is some \303\200\n\303\200 text", "\303\240", flags, 15, 16, "\303\200");
-  check_found_backward ("This is some \303\200\n\303\200 text", "a\314\200", flags, 15, 16, "\303\200");
-
-  /* end of buffer */
-  check_found_forward ("This is some\ntext foo", "foo", flags, 18, 21, "foo");
-  check_found_forward ("This is some\ntext foo", "Foo", flags, 18, 21, "foo");
-  check_found_forward ("This is some\ntext Foo", "foo", flags, 18, 21, "Foo");
-  check_found_forward ("This is some\ntext \303\200", "\303\240", flags, 18, 19, "\303\200");
-  check_found_forward ("This is some\ntext \303\200", "a\314\200", flags, 18, 19, "\303\200");
-  check_found_backward ("This is some\ntext foo", "foo", flags, 18, 21, "foo");
-  check_found_backward ("This is some\ntext foo", "Foo", flags, 18, 21, "foo");
-  check_found_backward ("This is some\ntext Foo", "foo", flags, 18, 21, "Foo");
-  check_found_backward ("This is some\ntext \303\200", "\303\240", flags, 18, 19, "\303\200");
-  check_found_backward ("This is some\ntext \303\200", "a\314\200", flags, 18, 19, "\303\200");
-
-  /* multiple lines in the needle */
-  check_found_forward ("This is some foo\nfoo text", "foo\nfoo", flags, 13, 20, "foo\nfoo");
-  check_found_forward ("This is some foo\nfoo text", "Foo\nFoo", flags, 13, 20, "foo\nfoo");
-  check_found_forward ("This is some Foo\nFoo text", "foo\nfoo", flags, 13, 20, "Foo\nFoo");
-  check_found_forward ("This is some \303\200\n\303\200 text", "\303\240\n\303\240", flags, 13, 16, "\303\200\n\303\200");
-  check_found_forward ("This is some \303\200\n\303\200 text", "a\314\200\na\314\200", flags, 13, 16, "\303\200\n\303\200");
-  check_found_backward ("This is some foo\nfoo text", "foo\nfoo", flags, 13, 20, "foo\nfoo");
-  check_found_backward ("This is some foo\nfoo text", "Foo\nFoo", flags, 13, 20, "foo\nfoo");
-  check_found_backward ("This is some Foo\nFoo text", "foo\nfoo", flags, 13, 20, "Foo\nFoo");
-  check_found_backward ("This is some \303\200\n\303\200 text", "\303\240\n\303\240", flags, 13, 16, "\303\200\n\303\200");
-  check_found_backward ("This is some \303\200\n\303\200 text", "a\314\200\na\314\200", flags, 13, 16, "\303\200\n\303\200");
-}
-
-int
-main (int argc, char** argv)
-{
-  gtk_test_init (&argc, &argv);
-
-  g_test_add_func ("/TextIter/Search Empty", test_empty_search);
-  g_test_add_func ("/TextIter/Search Full Buffer", test_full_buffer);
-  g_test_add_func ("/TextIter/Search", test_search);
-  g_test_add_func ("/TextIter/Search Caseless", test_search_caseless);
-
-  return g_test_run();
-}
diff --git a/gtk/tests/treemodel.c b/gtk/tests/treemodel.c
deleted file mode 100644 (file)
index 13eeb4f..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/* Main wrapper for TreeModel test suite.
- * Copyright (C) 2011  Kristian Rietveld  <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-#include "treemodel.h"
-
-int
-main (int    argc,
-      char **argv)
-{
-  gtk_test_init (&argc, &argv, NULL);
-
-  g_test_bug_base ("http://bugzilla.gnome.org/");
-
-  register_list_store_tests ();
-  register_tree_store_tests ();
-  register_model_ref_count_tests ();
-  register_sort_model_tests ();
-  register_filter_model_tests ();
-
-  return g_test_run ();
-}
-
-/*
- * Signal monitor
- */
-
-static const char *
-signal_name_to_string (SignalName signal)
-{
-  switch (signal)
-    {
-      case ROW_INSERTED:
-          return "row-inserted";
-
-      case ROW_DELETED:
-          return "row-deleted";
-
-      case ROW_CHANGED:
-          return "row-changed";
-
-      case ROW_HAS_CHILD_TOGGLED:
-          return "row-has-child-toggled";
-
-      case ROWS_REORDERED:
-          return "rows-reordered";
-
-      default:
-          /* Fall through */
-          break;
-    }
-
-  return "(unknown)";
-}
-
-typedef struct
-{
-  SignalName signal;
-  GtkTreePath *path;
-
-  /* For rows-reordered */
-  int *new_order;
-  int len;
-}
-Signal;
-
-
-static Signal *
-signal_new (SignalName signal, GtkTreePath *path)
-{
-  Signal *s;
-
-  s = g_new0 (Signal, 1);
-  s->signal = signal;
-  s->path = gtk_tree_path_copy (path);
-  s->new_order = NULL;
-
-  return s;
-}
-
-static Signal *
-signal_new_with_order (SignalName signal, GtkTreePath *path,
-                       int *new_order, int len)
-{
-  Signal *s = signal_new (signal, path);
-
-  s->new_order = new_order;
-  s->len = len;
-
-  return s;
-}
-
-static void
-signal_free (Signal *s)
-{
-  if (s->path)
-    gtk_tree_path_free (s->path);
-
-  g_free (s);
-}
-
-
-struct _SignalMonitor
-{
-  GQueue *queue;
-  GtkTreeModel *client;
-  gulong signal_ids[LAST_SIGNAL];
-};
-
-
-static void
-signal_monitor_generic_handler (SignalMonitor *m,
-                                SignalName     signal,
-                                GtkTreeModel  *model,
-                                GtkTreeIter   *iter,
-                                GtkTreePath   *path,
-                                int           *new_order)
-{
-  Signal *s;
-
-  if (g_queue_is_empty (m->queue))
-    {
-      gchar *path_str;
-
-      path_str = gtk_tree_path_to_string (path);
-      g_error ("Signal queue empty, got signal %s path %s\n",
-               signal_name_to_string (signal), path_str);
-      g_free (path_str);
-
-      g_assert_not_reached ();
-    }
-
-  if (m->client != model)
-    {
-      g_error ("Model mismatch; expected %p, got %p\n",
-               m->client, model);
-      g_assert_not_reached ();
-    }
-
-  s = g_queue_peek_tail (m->queue);
-
-#if 0
-  /* For debugging: output signals that are coming in.  Leaks memory. */
-  g_print ("signal=%s path=%s\n", signal_name_to_string (signal),
-           gtk_tree_path_to_string (path));
-#endif
-
-  if (s->signal != signal ||
-      (gtk_tree_path_get_depth (s->path) == 0 &&
-       gtk_tree_path_get_depth (path) != 0) ||
-      (gtk_tree_path_get_depth (s->path) != 0 &&
-       gtk_tree_path_compare (s->path, path) != 0))
-    {
-      gchar *path_str, *s_path_str;
-
-      s_path_str = gtk_tree_path_to_string (s->path);
-      path_str = gtk_tree_path_to_string (path);
-
-      g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n",
-               signal_name_to_string (s->signal), s_path_str,
-               signal_name_to_string (signal), path_str);
-
-      g_free (s_path_str);
-      g_free (path_str);
-
-      g_assert_not_reached ();
-    }
-
-  if (signal == ROWS_REORDERED && s->new_order != NULL)
-    {
-      int i, len;
-
-      g_assert (new_order != NULL);
-
-      len = gtk_tree_model_iter_n_children (model, iter);
-      g_assert (s->len == len);
-
-      for (i = 0; i < len; i++)
-        g_assert (s->new_order[i] == new_order[i]);
-    }
-
-  s = g_queue_pop_tail (m->queue);
-
-  signal_free (s);
-}
-
-static void
-signal_monitor_row_inserted (GtkTreeModel *model,
-                             GtkTreePath  *path,
-                             GtkTreeIter  *iter,
-                             gpointer      data)
-{
-  signal_monitor_generic_handler (data, ROW_INSERTED,
-                                  model, iter, path, NULL);
-}
-
-static void
-signal_monitor_row_deleted (GtkTreeModel *model,
-                            GtkTreePath  *path,
-                            gpointer      data)
-{
-  signal_monitor_generic_handler (data, ROW_DELETED,
-                                  model, NULL, path, NULL);
-}
-
-static void
-signal_monitor_row_changed (GtkTreeModel *model,
-                            GtkTreePath  *path,
-                            GtkTreeIter  *iter,
-                            gpointer      data)
-{
-  signal_monitor_generic_handler (data, ROW_CHANGED,
-                                  model, iter, path, NULL);
-}
-
-static void
-signal_monitor_row_has_child_toggled (GtkTreeModel *model,
-                                      GtkTreePath  *path,
-                                      GtkTreeIter  *iter,
-                                      gpointer      data)
-{
-  signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
-                                  model, iter, path, NULL);
-}
-
-static void
-signal_monitor_rows_reordered (GtkTreeModel *model,
-                               GtkTreePath  *path,
-                               GtkTreeIter  *iter,
-                               gint         *new_order,
-                               gpointer      data)
-{
-  signal_monitor_generic_handler (data, ROWS_REORDERED,
-                                  model, iter, path, new_order);
-}
-
-SignalMonitor *
-signal_monitor_new (GtkTreeModel *client)
-{
-  SignalMonitor *m;
-
-  m = g_new0 (SignalMonitor, 1);
-  m->client = g_object_ref (client);
-  m->queue = g_queue_new ();
-
-  m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
-                                                  "row-inserted",
-                                                  G_CALLBACK (signal_monitor_row_inserted),
-                                                  m);
-  m->signal_ids[ROW_DELETED] = g_signal_connect (client,
-                                                 "row-deleted",
-                                                 G_CALLBACK (signal_monitor_row_deleted),
-                                                 m);
-  m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
-                                                 "row-changed",
-                                                 G_CALLBACK (signal_monitor_row_changed),
-                                                 m);
-  m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
-                                                           "row-has-child-toggled",
-                                                           G_CALLBACK (signal_monitor_row_has_child_toggled),
-                                                           m);
-  m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
-                                                    "rows-reordered",
-                                                    G_CALLBACK (signal_monitor_rows_reordered),
-                                                    m);
-
-  return m;
-}
-
-void
-signal_monitor_free (SignalMonitor *m)
-{
-  int i;
-
-  for (i = 0; i < LAST_SIGNAL; i++)
-    g_signal_handler_disconnect (m->client, m->signal_ids[i]);
-
-  g_object_unref (m->client);
-
-  if (m->queue)
-    g_queue_free (m->queue);
-
-  g_free (m);
-}
-
-void
-signal_monitor_assert_is_empty (SignalMonitor *m)
-{
-  g_assert (g_queue_is_empty (m->queue));
-}
-
-void
-signal_monitor_append_signal_path (SignalMonitor *m,
-                                   SignalName     signal,
-                                   GtkTreePath   *path)
-{
-  Signal *s;
-
-  s = signal_new (signal, path);
-  g_queue_push_head (m->queue, s);
-}
-
-void
-signal_monitor_append_signal_reordered (SignalMonitor *m,
-                                        SignalName     signal,
-                                        GtkTreePath   *path,
-                                        int           *new_order,
-                                        int            len)
-{
-  Signal *s;
-
-  s = signal_new_with_order (signal, path, new_order, len);
-  g_queue_push_head (m->queue, s);
-}
-
-void
-signal_monitor_append_signal (SignalMonitor *m,
-                              SignalName     signal,
-                              const gchar   *path_string)
-{
-  Signal *s;
-  GtkTreePath *path;
-
-  path = gtk_tree_path_new_from_string (path_string);
-
-  s = signal_new (signal, path);
-  g_queue_push_head (m->queue, s);
-
-  gtk_tree_path_free (path);
-}
diff --git a/gtk/tests/treemodel.h b/gtk/tests/treemodel.h
deleted file mode 100644 (file)
index 3723057..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Main wrapper for TreeModel test suite.
- * Copyright (C) 2011  Kristian Rietveld  <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-void register_list_store_tests ();
-void register_tree_store_tests ();
-void register_sort_model_tests ();
-void register_filter_model_tests ();
-void register_model_ref_count_tests ();
-
-/*
- * Signal monitor
- */
-typedef struct _SignalMonitor           SignalMonitor;
-typedef enum _SignalName                SignalName;
-
-enum _SignalName
-{
-  ROW_INSERTED,
-  ROW_DELETED,
-  ROW_CHANGED,
-  ROW_HAS_CHILD_TOGGLED,
-  ROWS_REORDERED,
-  LAST_SIGNAL
-};
-
-
-SignalMonitor *signal_monitor_new                     (GtkTreeModel  *client);
-void           signal_monitor_free                    (SignalMonitor *m);
-
-void           signal_monitor_assert_is_empty         (SignalMonitor *m);
-
-void           signal_monitor_append_signal_reordered (SignalMonitor *m,
-                                                       SignalName     signal,
-                                                       GtkTreePath   *path,
-                                                       int           *new_order,
-                                                       int            len);
-void           signal_monitor_append_signal_path      (SignalMonitor *m,
-                                                       SignalName     signal,
-                                                       GtkTreePath   *path);
-void           signal_monitor_append_signal           (SignalMonitor *m,
-                                                       SignalName     signal,
-                                                       const gchar   *path_string);
diff --git a/gtk/tests/treepath.c b/gtk/tests/treepath.c
deleted file mode 100644 (file)
index c014de2..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/* GtkTrePath tests.
- *
- * Copyright (C) 2011, Red Hat, Inc.
- * Authors: Matthias Clasen <mclasen@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-static void
-test_append (void)
-{
-  GtkTreePath *p;
-  gint i;
-  gint *indices;
-
-  p = gtk_tree_path_new ();
-  for (i = 0; i < 100; i++)
-    {
-      g_assert_cmpint (gtk_tree_path_get_depth (p), ==, i);
-      gtk_tree_path_append_index (p, i);
-    }
-
-  indices = gtk_tree_path_get_indices (p);
-  for (i = 0; i < 100; i++)
-    g_assert_cmpint (indices[i], ==, i);
-
-  gtk_tree_path_free (p);
-}
-
-static void
-test_prepend (void)
-{
-  GtkTreePath *p;
-  gint i;
-  gint *indices;
-
-  p = gtk_tree_path_new ();
-  for (i = 0; i < 100; i++)
-    {
-      g_assert_cmpint (gtk_tree_path_get_depth (p), ==, i);
-      gtk_tree_path_prepend_index (p, i);
-    }
-
-  indices = gtk_tree_path_get_indices (p);
-  for (i = 0; i < 100; i++)
-    g_assert_cmpint (indices[i], ==, 99 - i);
-
-  gtk_tree_path_free (p);
-}
-
-static void
-test_to_string (void)
-{
-  const gchar *str = "0:1:2:3:4:5:6:7:8:9:10";
-  GtkTreePath *p;
-  gint *indices;
-  gchar *s;
-  gint i;
-
-  p = gtk_tree_path_new_from_string (str);
-  indices = gtk_tree_path_get_indices (p);
-  for (i = 0; i < 10; i++)
-    g_assert_cmpint (indices[i], ==, i);
-  s = gtk_tree_path_to_string (p);
-  g_assert_cmpstr (s, ==, str);
-
-  gtk_tree_path_free (p);
-  g_free (s);
-}
-
-static void
-test_from_indices (void)
-{
-  GtkTreePath *p;
-  gint *indices;
-  gint i;
-
-  p = gtk_tree_path_new_from_indices (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1);
-  g_assert_cmpint (gtk_tree_path_get_depth (p), ==, 10);
-  indices = gtk_tree_path_get_indices (p);
-  for (i = 0; i < 10; i++)
-    g_assert_cmpint (indices[i], ==, i);
-  gtk_tree_path_free (p);
-}
-
-static void
-test_first (void)
-{
-  GtkTreePath *p;
-  p = gtk_tree_path_new_first ();
-  g_assert_cmpint (gtk_tree_path_get_depth (p), ==, 1);
-  g_assert_cmpint (gtk_tree_path_get_indices (p)[0], ==, 0);
-  gtk_tree_path_free (p);
-}
-
-static void
-test_navigation (void)
-{
-  GtkTreePath *p;
-  GtkTreePath *q;
-  gint *pi;
-  gint *qi;
-  gint i;
-  gboolean res;
-
-  p = gtk_tree_path_new_from_indices (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1);
-  q = gtk_tree_path_copy (p);
-  g_assert (gtk_tree_path_compare (p, q) == 0);
-  gtk_tree_path_next (q);
-  pi = gtk_tree_path_get_indices (p);
-  qi = gtk_tree_path_get_indices (q);
-  for (i = 0; i < 9; i++)
-    g_assert_cmpint (pi[i], ==, qi[i]);
-  g_assert_cmpint (qi[9], ==, pi[9] + 1);
-
-  g_assert (!gtk_tree_path_is_ancestor (p, q));
-  g_assert (!gtk_tree_path_is_ancestor (q, p));
-  g_assert (!gtk_tree_path_is_descendant (p, q));
-  g_assert (!gtk_tree_path_is_descendant (q, p));
-
-  res = gtk_tree_path_prev (q);
-  g_assert (res);
-  g_assert (gtk_tree_path_compare (p, q) == 0);
-
-  g_assert (!gtk_tree_path_is_ancestor (p, q));
-  g_assert (!gtk_tree_path_is_ancestor (q, p));
-  g_assert (!gtk_tree_path_is_descendant (p, q));
-  g_assert (!gtk_tree_path_is_descendant (q, p));
-
-  gtk_tree_path_down (q);
-
-  g_assert (gtk_tree_path_compare (p, q) < 0);
-
-  g_assert (gtk_tree_path_is_ancestor (p, q));
-  g_assert (!gtk_tree_path_is_ancestor (q, p));
-  g_assert (!gtk_tree_path_is_descendant (p, q));
-  g_assert (gtk_tree_path_is_descendant (q, p));
-
-  res = gtk_tree_path_prev (q);
-  g_assert (!res);
-
-  res = gtk_tree_path_up (q);
-  g_assert (res);
-  g_assert (gtk_tree_path_compare (p, q) == 0);
-
-  g_assert_cmpint (gtk_tree_path_get_depth (q), ==, 10);
-  res = gtk_tree_path_up (q);
-  g_assert (res);
-  g_assert_cmpint (gtk_tree_path_get_depth (q), ==, 9);
-
-  gtk_tree_path_free (p);
-  gtk_tree_path_free (q);
-}
-
-int
-main (int argc, char *argv[])
-{
-  gtk_test_init (&argc, &argv, NULL);
-
-  g_test_add_func ("/tree-path/append", test_append);
-  g_test_add_func ("/tree-path/prepend", test_prepend);
-  g_test_add_func ("/tree-path/to-string", test_to_string);
-  g_test_add_func ("/tree-path/from-indices", test_from_indices);
-  g_test_add_func ("/tree-path/first", test_first);
-  g_test_add_func ("/tree-path/navigation", test_navigation);
-
-  return g_test_run ();
-}
diff --git a/gtk/tests/treestore.c b/gtk/tests/treestore.c
deleted file mode 100644 (file)
index d19297f..0000000
+++ /dev/null
@@ -1,1178 +0,0 @@
-/* Extensive GtkTreeStore tests.
- * Copyright (C) 2007  Imendio AB
- * Authors: Kristian Rietveld  <kris@imendio.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* To do:
- *  - All the to do items from liststore.c, plus:
- *  - Finish up the insertion tests; things aren't as nicely refactored
- *    here as in GtkListStore, so we need to check for corner cases on
- *    all insertion functions separately.
- *  - We only test in the root level, we also need all tests "duplicated"
- *    for child levels.
- *  - And we also need tests for creating these child levels, etc.
- */
-
-#include "treemodel.h"
-
-#include <gtk/gtk.h>
-
-static inline gboolean
-iters_equal (GtkTreeIter *a,
-            GtkTreeIter *b)
-{
-  if (a->stamp != b->stamp)
-    return FALSE;
-
-  if (a->user_data != b->user_data)
-    return FALSE;
-
-  /* user_data2 and user_data3 are not used in GtkTreeStore */
-
-  return TRUE;
-}
-
-static gboolean
-iter_position (GtkTreeStore *store,
-              GtkTreeIter  *iter,
-              int           n)
-{
-  gboolean ret = TRUE;
-  GtkTreePath *path;
-
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
-  if (!path)
-    return FALSE;
-
-  if (gtk_tree_path_get_indices (path)[0] != n)
-    ret = FALSE;
-
-  gtk_tree_path_free (path);
-
-  return ret;
-}
-
-/*
- * Fixture
- */
-typedef struct
-{
-  GtkTreeIter iter[5];
-  GtkTreeStore *store;
-} TreeStore;
-
-static void
-tree_store_setup (TreeStore     *fixture,
-                 gconstpointer  test_data)
-{
-  int i;
-
-  fixture->store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  for (i = 0; i < 5; i++)
-    {
-      gtk_tree_store_insert (fixture->store, &fixture->iter[i], NULL, i);
-      gtk_tree_store_set (fixture->store, &fixture->iter[i], 0, i, -1);
-    }
-}
-
-static void
-tree_store_teardown (TreeStore     *fixture,
-                    gconstpointer  test_data)
-{
-  g_object_unref (fixture->store);
-}
-
-/*
- * The actual tests.
- */
-
-static void
-check_model (TreeStore *fixture,
-            gint      *new_order,
-            gint       skip)
-{
-  int i;
-  GtkTreePath *path;
-
-  path = gtk_tree_path_new ();
-  gtk_tree_path_down (path);
-
-  /* Check validity of the model and validity of the iters-persistent
-   * claim.
-   */
-  for (i = 0; i < 5; i++)
-    {
-      GtkTreeIter iter;
-
-      if (i == skip)
-       continue;
-
-      /* The saved iterator at new_order[i] should match the iterator
-       * at i.
-       */
-
-      gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
-                              &iter, path);
-
-      g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter));
-      g_assert (iters_equal (&iter, &fixture->iter[new_order[i]]));
-
-      gtk_tree_path_next (path);
-    }
-
-  gtk_tree_path_free (path);
-}
-
-/* insertion */
-static void
-tree_store_test_insert_high_values (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_insert (store, &iter, NULL, 1234);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  gtk_tree_store_insert (store, &iter2, NULL, 765);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-tree_store_test_append (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  gtk_tree_store_append (store, &iter2, NULL);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-tree_store_test_prepend (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_prepend (store, &iter, NULL);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  gtk_tree_store_prepend (store, &iter2, NULL);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-tree_store_test_insert_after (void)
-{
-  GtkTreeIter iter, iter2, iter3;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_append (store, &iter2, NULL);
-
-  gtk_tree_store_insert_after (store, &iter3, NULL, &iter);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter3));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter3, 1));
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 1));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 2));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 2));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter3, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-tree_store_test_insert_after_NULL (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_append (store, &iter, NULL);
-
-  /* move_after NULL is basically a prepend */
-  gtk_tree_store_insert_after (store, &iter2, NULL, NULL);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
-  g_assert (iters_equal (&iter2, &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-tree_store_test_insert_before (void)
-{
-  GtkTreeIter iter, iter2, iter3;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_append (store, &iter, NULL);
-  gtk_tree_store_append (store, &iter2, NULL);
-
-  gtk_tree_store_insert_before (store, &iter3, NULL, &iter2);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter3));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter3, 1));
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 1));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter_copy, 2));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter3, &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 2));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter3, &iter_copy));
-  g_assert (iter_position (store, &iter3, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-static void
-tree_store_test_insert_before_NULL (void)
-{
-  GtkTreeIter iter, iter2;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  gtk_tree_store_append (store, &iter, NULL);
-
-  /* move_before NULL is basically an append */
-  gtk_tree_store_insert_before (store, &iter2, NULL, NULL);
-  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
-
-  /* Walk over the model */
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
-  g_assert (iters_equal (&iter2, &iter_copy));
-  g_assert (iter_position (store, &iter2, 1));
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (iter_position (store, &iter, 0));
-
-  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
-
-  g_object_unref (store);
-}
-
-/* setting values */
-static void
-tree_store_set_gvalue_to_transform (void)
-{
-  GtkTreeStore *store;
-  GtkTreeIter iter;
-  GValue value = G_VALUE_INIT;
-
-  /* https://bugzilla.gnome.org/show_bug.cgi?id=677649 */
-  store = gtk_tree_store_new (1, G_TYPE_LONG);
-  gtk_tree_store_append (store, &iter, NULL);
-
-  g_value_init (&value, G_TYPE_INT);
-  g_value_set_int (&value, 42);
-  gtk_tree_store_set_value (store, &iter, 0, &value);
-}
-
-/* removal */
-static void
-tree_store_test_remove_begin (TreeStore     *fixture,
-                             gconstpointer  user_data)
-{
-  int new_order[5] = { -1, 1, 2, 3, 4 };
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  /* Remove node at 0 */
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
-  gtk_tree_path_free (path);
-
-  g_assert (gtk_tree_store_remove (fixture->store, &iter) == TRUE);
-  g_assert (!gtk_tree_store_iter_is_valid (fixture->store, &fixture->iter[0]));
-  g_assert (iters_equal (&iter, &fixture->iter[1]));
-
-  check_model (fixture, new_order, 0);
-}
-
-static void
-tree_store_test_remove_middle (TreeStore     *fixture,
-                              gconstpointer  user_data)
-{
-  int new_order[5] = { 0, 1, -1, 3, 4 };
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  /* Remove node at 2 */
-  path = gtk_tree_path_new_from_indices (2, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
-  gtk_tree_path_free (path);
-
-  g_assert (gtk_tree_store_remove (fixture->store, &iter) == TRUE);
-  g_assert (!gtk_tree_store_iter_is_valid (fixture->store, &fixture->iter[2]));
-  g_assert (iters_equal (&iter, &fixture->iter[3]));
-
-  check_model (fixture, new_order, 2);
-}
-
-static void
-tree_store_test_remove_end (TreeStore     *fixture,
-                           gconstpointer  user_data)
-{
-  int new_order[5] = { 0, 1, 2, 3, -1 };
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  /* Remove node at 4 */
-  path = gtk_tree_path_new_from_indices (4, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
-  gtk_tree_path_free (path);
-
-  g_assert (gtk_tree_store_remove (fixture->store, &iter) == FALSE);
-  g_assert (!gtk_tree_store_iter_is_valid (fixture->store, &fixture->iter[4]));
-
-  check_model (fixture, new_order, 4);
-}
-
-static void
-tree_store_test_clear (TreeStore     *fixture,
-                      gconstpointer  user_data)
-{
-  int i;
-
-  gtk_tree_store_clear (fixture->store);
-
-  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL) == 0);
-
-  for (i = 0; i < 5; i++)
-    g_assert (!gtk_tree_store_iter_is_valid (fixture->store, &fixture->iter[i]));
-}
-
-/* reorder */
-
-static void
-tree_store_test_reorder (TreeStore     *fixture,
-                        gconstpointer  user_data)
-{
-  int new_order[5] = { 4, 1, 0, 2, 3 };
-
-  gtk_tree_store_reorder (fixture->store, NULL, new_order);
-  check_model (fixture, new_order, -1);
-}
-
-/* swapping */
-
-static void
-tree_store_test_swap_begin (TreeStore     *fixture,
-                           gconstpointer  user_data)
-{
-  /* We swap nodes 0 and 1 at the beginning */
-  int new_order[5] = { 1, 0, 2, 3, 4 };
-
-  GtkTreeIter iter_a;
-  GtkTreeIter iter_b;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
-
-  gtk_tree_store_swap (fixture->store, &iter_a, &iter_b);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_swap_middle_next (TreeStore     *fixture,
-                                 gconstpointer  user_data)
-{
-  /* We swap nodes 2 and 3 in the middle that are next to each other */
-  int new_order[5] = { 0, 1, 3, 2, 4 };
-
-  GtkTreeIter iter_a;
-  GtkTreeIter iter_b;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "2"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
-
-  gtk_tree_store_swap (fixture->store, &iter_a, &iter_b);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_swap_middle_apart (TreeStore     *fixture,
-                                  gconstpointer  user_data)
-{
-  /* We swap nodes 1 and 3 in the middle that are apart from each other */
-  int new_order[5] = { 0, 3, 2, 1, 4 };
-
-  GtkTreeIter iter_a;
-  GtkTreeIter iter_b;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "1"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
-
-  gtk_tree_store_swap (fixture->store, &iter_a, &iter_b);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_swap_end (TreeStore     *fixture,
-                         gconstpointer  user_data)
-{
-  /* We swap nodes 3 and 4 at the end */
-  int new_order[5] = { 0, 1, 2, 4, 3 };
-
-  GtkTreeIter iter_a;
-  GtkTreeIter iter_b;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "3"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
-
-  gtk_tree_store_swap (fixture->store, &iter_a, &iter_b);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_swap_single (void)
-{
-  GtkTreeIter iter;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  /* Check if swap on a store with a single node does not corrupt
-   * the store.
-   */
-
-  gtk_tree_store_append (store, &iter, NULL);
-  iter_copy = iter;
-
-  gtk_tree_store_swap (store, &iter, &iter);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  g_object_unref (store);
-}
-
-/* move after */
-
-static void
-tree_store_test_move_after_from_start (TreeStore     *fixture,
-                                      gconstpointer  user_data)
-{
-  /* We move node 0 after 2 */
-  int new_order[5] = { 1, 2, 0, 3, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
-
-  gtk_tree_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_after_next (TreeStore     *fixture,
-                                gconstpointer  user_data)
-{
-  /* We move node 2 after 3 */
-  int new_order[5] = { 0, 1, 3, 2, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
-
-  gtk_tree_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_after_apart (TreeStore     *fixture,
-                                 gconstpointer  user_data)
-{
-  /* We move node 1 after 3 */
-  int new_order[5] = { 0, 2, 3, 1, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
-
-  gtk_tree_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_after_end (TreeStore     *fixture,
-                               gconstpointer  user_data)
-{
-  /* We move node 2 after 4 */
-  int new_order[5] = { 0, 1, 3, 4, 2 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
-
-  gtk_tree_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_after_from_end (TreeStore     *fixture,
-                                    gconstpointer  user_data)
-{
-  /* We move node 4 after 1 */
-  int new_order[5] = { 0, 1, 4, 2, 3 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
-
-  gtk_tree_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_after_change_ends (TreeStore     *fixture,
-                                       gconstpointer  user_data)
-{
-  /* We move 0 after 4, this will cause both the head and tail ends to
-   * change.
-   */
-  int new_order[5] = { 1, 2, 3, 4, 0 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
-
-  gtk_tree_store_move_after (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_after_NULL (TreeStore     *fixture,
-                                gconstpointer  user_data)
-{
-  /* We move node 2, NULL should prepend */
-  int new_order[5] = { 2, 0, 1, 3, 4 };
-
-  GtkTreeIter iter;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-
-  gtk_tree_store_move_after (fixture->store, &iter, NULL);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_after_single (void)
-{
-  GtkTreeIter iter;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  /* Check if move-after on a store with a single node does not corrupt
-   * the store.
-   */
-
-  gtk_tree_store_append (store, &iter, NULL);
-  iter_copy = iter;
-
-  gtk_tree_store_move_after (store, &iter, NULL);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  gtk_tree_store_move_after (store, &iter, &iter);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  g_object_unref (store);
-}
-
-/* move before */
-
-static void
-tree_store_test_move_before_next (TreeStore     *fixture,
-                                 gconstpointer  user_data)
-{
-  /* We move node 3 before 2 */
-  int new_order[5] = { 0, 1, 3, 2, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
-
-  gtk_tree_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_before_apart (TreeStore     *fixture,
-                                  gconstpointer  user_data)
-{
-  /* We move node 1 before 3 */
-  int new_order[5] = { 0, 2, 1, 3, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
-
-  gtk_tree_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_before_to_start (TreeStore     *fixture,
-                                     gconstpointer  user_data)
-{
-  /* We move node 2 before 0 */
-  int new_order[5] = { 2, 0, 1, 3, 4 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
-
-  gtk_tree_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_before_from_end (TreeStore     *fixture,
-                                     gconstpointer  user_data)
-{
-  /* We move node 4 before 2 (replace end) */
-  int new_order[5] = { 0, 1, 4, 2, 3 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
-
-  gtk_tree_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_before_change_ends (TreeStore     *fixture,
-                                        gconstpointer  user_data)
-{
-  /* We move node 4 before 0 */
-  int new_order[5] = { 4, 0, 1, 2, 3 };
-
-  GtkTreeIter iter;
-  GtkTreeIter position;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
-
-  gtk_tree_store_move_before (fixture->store, &iter, &position);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_before_NULL (TreeStore     *fixture,
-                                 gconstpointer  user_data)
-{
-  /* We move node 2, NULL should append */
-  int new_order[5] = { 0, 1, 3, 4, 2 };
-
-  GtkTreeIter iter;
-
-  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
-
-  gtk_tree_store_move_before (fixture->store, &iter, NULL);
-  check_model (fixture, new_order, -1);
-}
-
-static void
-tree_store_test_move_before_single (void)
-{
-  GtkTreeIter iter;
-  GtkTreeIter iter_copy;
-  GtkTreeStore *store;
-
-  store = gtk_tree_store_new (1, G_TYPE_INT);
-
-  /* Check if move-after on a store with a single node does not corrupt
-   * the store.
-   */
-
-  gtk_tree_store_append (store, &iter, NULL);
-  iter_copy = iter;
-
-  gtk_tree_store_move_before (store, &iter, NULL);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  gtk_tree_store_move_before (store, &iter, &iter);
-  g_assert (iters_equal (&iter, &iter_copy));
-  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
-  g_assert (iters_equal (&iter, &iter_copy));
-
-  g_object_unref (store);
-}
-
-
-/* iter invalidation */
-
-static void
-tree_store_test_iter_previous_invalid (TreeStore     *fixture,
-                                       gconstpointer  user_data)
-{
-  GtkTreeIter iter;
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
-
-  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
-                                          &iter) == FALSE);
-  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
-  g_assert (iter.stamp == 0);
-}
-
-static void
-tree_store_test_iter_next_invalid (TreeStore     *fixture,
-                                   gconstpointer  user_data)
-{
-  GtkTreePath *path;
-  GtkTreeIter iter;
-
-  path = gtk_tree_path_new_from_indices (4, -1);
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
-  gtk_tree_path_free (path);
-
-  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
-                                      &iter) == FALSE);
-  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
-  g_assert (iter.stamp == 0);
-}
-
-static void
-tree_store_test_iter_children_invalid (TreeStore     *fixture,
-                                       gconstpointer  user_data)
-{
-  GtkTreeIter iter, child;
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
-  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == TRUE);
-
-  g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
-                                          &child, &iter) == FALSE);
-  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == FALSE);
-  g_assert (child.stamp == 0);
-}
-
-static void
-tree_store_test_iter_nth_child_invalid (TreeStore     *fixture,
-                                        gconstpointer  user_data)
-{
-  GtkTreeIter iter, child;
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
-  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == TRUE);
-
-  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
-                                           &child, &iter, 0) == FALSE);
-  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == FALSE);
-  g_assert (child.stamp == 0);
-}
-
-static void
-tree_store_test_iter_parent_invalid (TreeStore     *fixture,
-                                     gconstpointer  user_data)
-{
-  GtkTreeIter iter, child;
-
-  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child);
-  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == TRUE);
-
-  g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
-                                        &iter, &child) == FALSE);
-  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
-  g_assert (iter.stamp == 0);
-}
-
-/* specific bugs */
-static void
-specific_bug_77977 (void)
-{
-  GtkTreeStore *tree_store;
-  GtkTreeIter iter1, iter2, iter3;
-  GtkTreePath *path;
-  GtkTreeRowReference *row_ref;
-
-  /* Stripped down version of test case for bug 77977 by Damon Chaplin */
-
-  g_test_bug ("77977");
-
-  tree_store = gtk_tree_store_new (1, G_TYPE_STRING);
-
-  gtk_tree_store_append (tree_store, &iter1, NULL);
-  gtk_tree_store_set (tree_store, &iter1, 0, "Window1", -1);
-
-  gtk_tree_store_append (tree_store, &iter2, &iter1);
-  gtk_tree_store_set (tree_store, &iter2, 0, "Table1", -1);
-
-  gtk_tree_store_append (tree_store, &iter3, &iter2);
-  gtk_tree_store_set (tree_store, &iter3, 0, "Button1", -1);
-
-  path = gtk_tree_path_new_from_indices (0, 0, 0, -1);
-  row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (tree_store), path);
-  gtk_tree_path_free (path);
-
-  gtk_tree_store_remove (tree_store, &iter1);
-
-  gtk_tree_row_reference_free (row_ref);
-  g_object_unref (tree_store);
-}
-
-/* main */
-
-void
-register_tree_store_tests (void)
-{
-  /* insertion */
-  g_test_add_func ("/TreeStore/insert-high-values",
-                  tree_store_test_insert_high_values);
-  g_test_add_func ("/TreeStore/append",
-                  tree_store_test_append);
-  g_test_add_func ("/TreeStore/prepend",
-                  tree_store_test_prepend);
-  g_test_add_func ("/TreeStore/insert-after",
-                  tree_store_test_insert_after);
-  g_test_add_func ("/TreeStore/insert-after-NULL",
-                  tree_store_test_insert_after_NULL);
-  g_test_add_func ("/TreeStore/insert-before",
-                  tree_store_test_insert_before);
-  g_test_add_func ("/TreeStore/insert-before-NULL",
-                  tree_store_test_insert_before_NULL);
-
-  /* setting values (FIXME) */
-  g_test_add_func ("/TreeStore/set-gvalue-to-transform",
-                   tree_store_set_gvalue_to_transform);
-
-  /* removal */
-  g_test_add ("/TreeStore/remove-begin", TreeStore, NULL,
-             tree_store_setup, tree_store_test_remove_begin,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/remove-middle", TreeStore, NULL,
-             tree_store_setup, tree_store_test_remove_middle,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/remove-end", TreeStore, NULL,
-             tree_store_setup, tree_store_test_remove_end,
-             tree_store_teardown);
-
-  g_test_add ("/TreeStore/clear", TreeStore, NULL,
-             tree_store_setup, tree_store_test_clear,
-             tree_store_teardown);
-
-  /* reordering */
-  g_test_add ("/TreeStore/reorder", TreeStore, NULL,
-             tree_store_setup, tree_store_test_reorder,
-             tree_store_teardown);
-
-  /* swapping */
-  g_test_add ("/TreeStore/swap-begin", TreeStore, NULL,
-             tree_store_setup, tree_store_test_swap_begin,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/swap-middle-next", TreeStore, NULL,
-             tree_store_setup, tree_store_test_swap_middle_next,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/swap-middle-apart", TreeStore, NULL,
-             tree_store_setup, tree_store_test_swap_middle_apart,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/swap-end", TreeStore, NULL,
-             tree_store_setup, tree_store_test_swap_end,
-             tree_store_teardown);
-  g_test_add_func ("/TreeStore/swap-single",
-                  tree_store_test_swap_single);
-
-  /* moving */
-  g_test_add ("/TreeStore/move-after-from-start", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_after_from_start,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-after-next", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_after_next,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-after-apart", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_after_apart,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-after-end", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_after_end,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-after-from-end", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_after_from_end,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-after-change-ends", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_after_change_ends,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-after-NULL", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_after_NULL,
-             tree_store_teardown);
-  g_test_add_func ("/TreeStore/move-after-single",
-                  tree_store_test_move_after_single);
-
-  g_test_add ("/TreeStore/move-before-next", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_before_next,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-before-apart", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_before_apart,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-before-to-start", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_before_to_start,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-before-from-end", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_before_from_end,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-before-change-ends", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_before_change_ends,
-             tree_store_teardown);
-  g_test_add ("/TreeStore/move-before-NULL", TreeStore, NULL,
-             tree_store_setup, tree_store_test_move_before_NULL,
-             tree_store_teardown);
-  g_test_add_func ("/TreeStore/move-before-single",
-                  tree_store_test_move_before_single);
-
-  /* iter invalidation */
-  g_test_add ("/TreeStore/iter-prev-invalid", TreeStore, NULL,
-              tree_store_setup, tree_store_test_iter_previous_invalid,
-              tree_store_teardown);
-  g_test_add ("/TreeStore/iter-next-invalid", TreeStore, NULL,
-              tree_store_setup, tree_store_test_iter_next_invalid,
-              tree_store_teardown);
-  g_test_add ("/TreeStore/iter-children-invalid", TreeStore, NULL,
-              tree_store_setup, tree_store_test_iter_children_invalid,
-              tree_store_teardown);
-  g_test_add ("/TreeStore/iter-nth-child-invalid", TreeStore, NULL,
-              tree_store_setup, tree_store_test_iter_nth_child_invalid,
-              tree_store_teardown);
-  g_test_add ("/TreeStore/iter-parent-invalid", TreeStore, NULL,
-              tree_store_setup, tree_store_test_iter_parent_invalid,
-              tree_store_teardown);
-
-  /* specific bugs */
-  g_test_add_func ("/TreeStore/bug-77977", specific_bug_77977);
-}
diff --git a/gtk/tests/treeview-scrolling.c b/gtk/tests/treeview-scrolling.c
deleted file mode 100644 (file)
index 77dca9a..0000000
+++ /dev/null
@@ -1,1494 +0,0 @@
-/* Scrolling test suite for GtkTreeView
- * Copyright (C) 2006  Kristian Rietveld  <kris@gtk.org>
- * Copyright (C) 2007  Imendio AB,  Kristian Rietveld
- * Copyright (C) 2009  Kristian Rietveld  <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Original v1.0 -- December 26, 2006
- * Conversion to GLib/GTK+ test framework during December, 2007
- */
-
-
-#include <gtk/gtk.h>
-#include <unistd.h>
-#include <math.h>
-
-#define VIEW_WIDTH 320
-#define VIEW_HEIGHT 240
-
-#define N_ROWS 1000
-#define BIG_N_ROWS N_ROWS * 100
-
-/*
- * To do:
- *   - Test that nothing happens if the row is fully visible.
- *   - The tests are dependent on the theme/font (size measurements,
- *     chosen paths).
- *   - Convert to proper GTK+ coding style.
- *   - Briefly test scrolling in tree stores as well.
- *
- * Important:
- *   - For tests with "mixed height" models, you must ensure that
- *     there are only two heights used in total and that the rows with
- *     height A and B are strictly alternating.  The model creation
- *     functions already do this for you, but take this into account
- *     when you write a unit test that adds rows to such a created
- *     model, you must follow this rule otherwise things will break.
- */
-
-
-/* Constructing models for testing */
-static GtkTreeModel *
-create_model (gboolean constant)
-{
-       int i;
-
-       GtkTreeIter iter;
-       GtkListStore *store;
-
-       store = gtk_list_store_new (1, G_TYPE_STRING);
-
-       for (i = 0; i < N_ROWS; i++) {
-               gtk_list_store_append (store, &iter);
-               if (constant || i % 2 == 0)
-                       gtk_list_store_set (store, &iter, 0, "Foo", -1);
-               else
-                       gtk_list_store_set (store, &iter, 0, "Sliff\nSloff\nBleh", -1);
-       }
-
-       return GTK_TREE_MODEL (store);
-}
-
-static GtkTreeModel *
-create_big_model (gboolean constant)
-{
-       int i;
-
-       GtkTreeIter iter;
-       GtkListStore *store;
-
-       store = gtk_list_store_new (1, G_TYPE_STRING);
-
-       for (i = 0; i < BIG_N_ROWS; i++) {
-               gtk_list_store_append (store, &iter);
-               if (constant || i % 2 == 0)
-                       gtk_list_store_set (store, &iter, 0, "Foo", -1);
-               else
-                       gtk_list_store_set (store, &iter, 0, "Sliff\nSloff\nBleh", -1);
-       }
-
-       return GTK_TREE_MODEL (store);
-}
-
-/*
- * Fixtures
- */
-
-typedef struct
-{
-       GtkWidget *window;
-       GtkWidget *tree_view;
-}
-ScrollFixture;
-
-static void
-scroll_fixture_setup (ScrollFixture *fixture,
-                     GtkTreeModel  *model,
-                     gconstpointer  test_data)
-{
-       GtkWidget *sw;
-       GtkCellRenderer *renderer;
-       GtkTreeViewColumn *column;
-
-       fixture->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
-       sw = gtk_scrolled_window_new (NULL, NULL);
-       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
-                                       GTK_POLICY_NEVER,
-                                       GTK_POLICY_ALWAYS);
-       gtk_container_add (GTK_CONTAINER (fixture->window), sw);
-
-       fixture->tree_view = gtk_tree_view_new_with_model (model);
-       g_object_unref (model);
-       gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (sw), VIEW_WIDTH);
-       gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), VIEW_HEIGHT);
-       gtk_widget_set_size_request (fixture->tree_view, VIEW_WIDTH, VIEW_HEIGHT);
-
-       renderer = gtk_cell_renderer_text_new ();
-       g_object_set (renderer, "editable", TRUE, NULL);
-       column = gtk_tree_view_column_new_with_attributes ("Title",
-                                                          renderer,
-                                                          "text", 0,
-                                                          NULL);
-
-       gtk_tree_view_append_column (GTK_TREE_VIEW (fixture->tree_view), column);
-       gtk_container_add (GTK_CONTAINER (sw), fixture->tree_view);
-}
-
-/* sets up a fixture with a model with constant row heights */
-static void
-scroll_fixture_constant_setup (ScrollFixture *fixture,
-                              gconstpointer  test_data)
-{
-       scroll_fixture_setup (fixture, create_model (TRUE), test_data);
-}
-
-/* sets up a fixture with a model with varying row heights */
-static void
-scroll_fixture_mixed_setup (ScrollFixture *fixture,
-                           gconstpointer  test_data)
-{
-       scroll_fixture_setup (fixture, create_model (FALSE), test_data);
-}
-
-/* sets up a fixture with a large model with constant row heights */
-static void
-scroll_fixture_constant_big_setup (ScrollFixture *fixture,
-                                  gconstpointer  test_data)
-{
-       scroll_fixture_setup (fixture, create_big_model (TRUE), test_data);
-}
-
-/* sets up a fixture with a large model with varying row heights */
-static void
-scroll_fixture_mixed_big_setup (ScrollFixture *fixture,
-                               gconstpointer  test_data)
-{
-       scroll_fixture_setup (fixture, create_big_model (FALSE), test_data);
-}
-
-/* sets up a fixture with only a single row for the "single row scroll" test */
-static void
-scroll_fixture_single_setup (ScrollFixture *fixture,
-                            gconstpointer  test_data)
-{
-       GtkTreeStore *store;
-       GtkTreeIter iter, child;
-
-       store = gtk_tree_store_new (1, G_TYPE_STRING);
-
-       gtk_tree_store_append (store, &iter, NULL);
-       gtk_tree_store_set (store, &iter, 0, "Foo", -1);
-
-       gtk_tree_store_append (store, &child, &iter);
-       gtk_tree_store_set (store, &child, 0, "Two\nLines", -1);
-
-       /* The teardown will also destroy the model */
-       scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), test_data);
-}
-
-/* sets up a fixture with a tree store */
-static void
-scroll_fixture_tree_setup (ScrollFixture *fixture,
-                          gconstpointer   test_data)
-{
-       GtkTreeStore *store;
-       GtkTreeIter iter, child;
-       int i;
-
-       store = gtk_tree_store_new (1, G_TYPE_STRING);
-
-       gtk_tree_store_append (store, &iter, NULL);
-       gtk_tree_store_set (store, &iter, 0, "Root node", -1);
-
-       for (i = 0; i < 5; i++) {
-               gtk_tree_store_append (store, &child, &iter);
-               gtk_tree_store_set (store, &child, 0, "Child node", -1);
-       }
-
-       for (i = 0; i < 5; i++) {
-               gtk_tree_store_append (store, &iter, NULL);
-               gtk_tree_store_set (store, &iter, 0, "Other node", -1);
-       }
-
-       /* The teardown will also destroy the model */
-       scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), test_data);
-}
-
-static void
-scroll_fixture_mixed_tree_setup (ScrollFixture *fixture,
-                                gconstpointer   test_data)
-{
-       GtkTreeStore *store;
-       GtkTreeIter iter, child;
-       int i;
-
-       store = gtk_tree_store_new (1, G_TYPE_STRING);
-
-       gtk_tree_store_append (store, &iter, NULL);
-       gtk_tree_store_set (store, &iter, 0, "Root\nnode", -1);
-
-       for (i = 0; i < 5; i++) {
-               gtk_tree_store_append (store, &child, &iter);
-               if (i % 2 != 0)
-                       gtk_tree_store_set (store, &child, 0, "Child node", -1);
-               else
-                       gtk_tree_store_set (store, &child,
-                                           0, "Child\nnode", -1);
-       }
-
-       for (i = 0; i < 5; i++) {
-               gtk_tree_store_append (store, &iter, NULL);
-               if (i % 2 == 0)
-                       gtk_tree_store_set (store, &iter, 0, "Other node", -1);
-               else
-                       gtk_tree_store_set (store, &iter, 0, "Other\nnode", -1);
-       }
-
-       /* The teardown will also destroy the model */
-       scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), test_data);
-}
-
-static void
-scroll_fixture_teardown (ScrollFixture *fixture,
-                        gconstpointer  test_data)
-{
-       gtk_widget_destroy (fixture->window);
-}
-
-/*
- * Position check and helpers.
- */
-enum Pos
-{
-       POS_TOP,
-       POS_CENTER,
-       POS_BOTTOM
-};
-
-static int
-get_row_start_for_index (GtkTreeView *tree_view, int index)
-{
-       gint height1, height2;
-       gint row_start;
-       GtkTreePath *path;
-       GdkRectangle rect;
-
-       path = gtk_tree_path_new_from_indices (0, -1);
-       gtk_tree_view_get_background_area (tree_view, path, NULL, &rect);
-       height1 = rect.height;
-
-       gtk_tree_path_next (path);
-       gtk_tree_view_get_background_area (tree_view, path, NULL, &rect);
-       height2 = rect.height;
-       gtk_tree_path_free (path);
-
-       row_start = (index / 2) * height1 + (index / 2) * height2;
-       if (index % 2)
-               row_start += height1;
-
-       return row_start;
-}
-
-static enum Pos
-get_pos_from_path (GtkTreeView   *tree_view,
-                  GtkTreePath   *path,
-                  gdouble        row_height,
-                  GtkAdjustment *vadjustment)
-{
-       int row_start;
-
-       row_start = get_row_start_for_index (tree_view,
-                                            gtk_tree_path_get_indices (path)[0]);
-
-       if (row_start + row_height < gtk_adjustment_get_page_size (vadjustment))
-               return POS_TOP;
-
-       if (row_start >= gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment))
-               return POS_BOTTOM;
-
-       return POS_CENTER;
-}
-
-static void
-assert_position_with_align (GtkTreeView  *tree_view,
-                            enum Pos      pos,
-                            gint          row_y,
-                            gint          row_start,
-                            gdouble       row_height,
-                            gdouble       row_align)
-{
-       GtkAdjustment *vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (tree_view));
-
-       /* Switch on row-align: 0.0, 0.5, 1.0 */
-       switch ((int)(row_align * 2.)) {
-       case 0:
-               if (pos == POS_TOP || pos == POS_CENTER) {
-                       /* The row in question is the first row
-                        * in the view.
-                        *    - rect.y should be zero
-                        *    - dy should be equal to the top
-                        *      y coordinate of the row.
-                        */
-                       g_assert (row_y == 0);
-                       g_assert (gtk_adjustment_get_value (vadjustment) == row_start);
-               } else {
-                       /* The row can be anywhere at the last
-                        * page of the tree view.
-                        *   - dy is set to the start of the
-                        *     last page.
-                        */
-                       g_assert (gtk_adjustment_get_value (vadjustment) == gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment));
-               }
-               break;
-
-       case 1:
-               /* 0.5 */
-               if (pos == POS_TOP
-                   && row_start < (gtk_adjustment_get_page_size (vadjustment) - row_height) / 2) {
-                       /* For the first half of the top view we can't
-                        * center the row in the view, instead we
-                        * show the first page.
-                        *   - dy should be zero
-                        */
-                       g_assert (gtk_adjustment_get_value (vadjustment) == 0);
-               } else if (pos == POS_BOTTOM
-                          && row_start + row_height >= gtk_adjustment_get_upper (vadjustment) - (gtk_adjustment_get_page_size (vadjustment) - row_height) / 2) {
-                       /* For the last half of the bottom view we
-                        * can't center the row in the view, instead
-                        * we show the last page.
-                        *   - dy should be the start of the 
-                        *     last page.
-                        */
-                       g_assert (gtk_adjustment_get_value (vadjustment) == gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment));
-               } else {
-                       /* The row is located in the middle of
-                        * the view.
-                        *    - top y coordinate is equal to
-                        *      middle of the view minus
-                        *      half the height of the row.
-                        *      (ie. the row's center is at the
-                        *       center of the view).
-                        */
-                       gdouble middle = (gtk_adjustment_get_page_size (vadjustment) - row_height) / 2.0;
-                       g_assert (row_y == ceil (middle) || row_y == floor (middle));
-               }
-               break;
-
-       case 2:
-               /* 1.0 */
-               if (pos == POS_TOP) {
-                       /* The row can be anywhere on the
-                        * first page of the tree view.
-                        *   - dy is zero.
-                        */
-                       g_assert (gtk_adjustment_get_value (vadjustment) == 0);
-               } else if (pos == POS_CENTER || pos == POS_BOTTOM) {
-                       /* The row is the last row visible in the
-                        * view.
-                        *   - rect.y is set to the top of the
-                        *     last row.
-                        *   - row_start is greater than page_size
-                        *     (ie we are not on the first page).
-                        *   - dy is greater than zero
-                        */
-                       g_assert (row_start >= gtk_adjustment_get_page_size (vadjustment)
-                                 || row_start + row_height >= gtk_adjustment_get_page_size (vadjustment));
-                       g_assert (row_y == gtk_adjustment_get_page_size (vadjustment) - row_height);
-               }
-               break;
-       }
-}
-
-static void
-assert_position_without_align (GtkTreeView *tree_view,
-                               gdouble      row_start,
-                               gdouble      row_height)
-{
-  GtkAdjustment *vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (tree_view));
-
-  /* Without align the tree view does as less work as possible,
-   * so basically we only have to check whether the row
-   * is visible on the screen.
-   */
-  g_assert (gtk_adjustment_get_value (vadjustment) <= row_start);
-  g_assert (gtk_adjustment_get_value (vadjustment) + gtk_adjustment_get_page_size (vadjustment) >= row_start + row_height);
-}
-
-static void
-test_position (GtkTreeView *tree_view,
-              GtkTreePath *path,
-              gboolean     use_align,
-              gdouble      row_align)
-{
-       gint pos;
-       gchar *path_str;
-       GdkRectangle rect;
-       GtkTreeModel *model;
-       gint row_start;
-
-       /* Get the location of the path we scrolled to */
-       gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
-                                          path, NULL, &rect);
-
-       row_start = get_row_start_for_index (GTK_TREE_VIEW (tree_view),
-                                            gtk_tree_path_get_indices (path)[0]);
-
-       /* Ugh */
-       pos = get_pos_from_path (GTK_TREE_VIEW (tree_view),
-                                path, rect.height,
-                                gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (tree_view)));
-
-       /* This is only tested for during test_single() */
-       model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
-       if (gtk_tree_model_iter_n_children (model, NULL) == 1) {
-                GtkAllocation allocation;
-               GtkTreePath *tmppath;
-
-               /* Test nothing is dangling at the bottom; read
-                * description for test_single() for more information.
-                */
-
-               /* FIXME: hardcoded width */
-                gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
-               if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree_view), 0, allocation.height - 30, &tmppath, NULL, NULL, NULL)) {
-                       g_assert_not_reached ();
-                       gtk_tree_path_free (tmppath);
-               }
-       }
-
-       path_str = gtk_tree_path_to_string (path);
-       if (use_align) {
-               assert_position_with_align (tree_view, pos, rect.y,
-                                            row_start, rect.height, row_align);
-       } else {
-               assert_position_without_align (tree_view, row_start, rect.height);
-       }
-
-       g_free (path_str);
-}
-
-/*
- * Scrolling code
- */
-
-
-/* Testing scrolling to various positions with various alignments */
-
-static void
-ensure_layout (void)
-{
-        /* HACK: sleep for more than one frame, to give the paint clock
-         * time to prepare the new layout */
-        g_usleep (100 * 1000);
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-}
-
-static void
-scroll (ScrollFixture *fixture,
-       GtkTreePath   *path,
-       gboolean       use_align,
-       gdouble        row_align)
-{
-       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view), path,
-                                 NULL, FALSE);
-       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
-                                     path, NULL,
-                                     use_align, row_align, 0.0);
-
-       gtk_widget_show_all (fixture->window);
-
-        ensure_layout ();
-       test_position (GTK_TREE_VIEW (fixture->tree_view), path,
-                      use_align, row_align);
-}
-
-static void
-scroll_no_align (ScrollFixture *fixture,
-                gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll (fixture, path, FALSE, 0.0);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_align_0_0 (ScrollFixture *fixture,
-                 gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll (fixture, path, TRUE, 0.0);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_align_0_5 (ScrollFixture *fixture,
-                 gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll (fixture, path, TRUE, 0.5);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_align_1_0 (ScrollFixture *fixture,
-                 gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll (fixture, path, TRUE, 1.0);
-       gtk_tree_path_free (path);
-}
-
-
-static void
-scroll_after_realize (ScrollFixture *fixture,
-                     GtkTreePath   *path,
-                     gboolean       use_align,
-                     gdouble        row_align)
-{
-       gtk_widget_show_all (fixture->window);
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view), path,
-                                 NULL, FALSE);
-       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
-                                     path, NULL,
-                                     use_align, row_align, 0.0);
-
-        ensure_layout ();
-       test_position (GTK_TREE_VIEW (fixture->tree_view), path,
-                      use_align, row_align);
-}
-
-static void
-scroll_after_no_align (ScrollFixture *fixture,
-                      gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll_after_realize (fixture, path, FALSE, 0.0);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_after_align_0_0 (ScrollFixture *fixture,
-                       gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll_after_realize (fixture, path, TRUE, 0.0);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_after_align_0_5 (ScrollFixture *fixture,
-                       gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll_after_realize (fixture, path, TRUE, 0.5);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_after_align_1_0 (ScrollFixture *fixture,
-                       gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll_after_realize (fixture, path, TRUE, 1.0);
-       gtk_tree_path_free (path);
-}
-
-
-static void
-scroll_both_realize (ScrollFixture *fixture,
-                    GtkTreePath   *path,
-                    gboolean       use_align,
-                    gdouble        row_align)
-{
-       GtkTreePath *end;
-
-       gtk_widget_show_all (fixture->window);
-
-       /* Scroll to end */
-       end = gtk_tree_path_new_from_indices (999, -1);
-
-       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view), end,
-                                 NULL, FALSE);
-       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
-                                     end, NULL,
-                                     use_align, row_align, 0.0);
-       gtk_tree_path_free (end);
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       /* Scroll to final position */
-       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view), path,
-                                 NULL, FALSE);
-       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
-                                     path, NULL,
-                                     use_align, row_align, 0.0);
-
-        ensure_layout ();
-       test_position (GTK_TREE_VIEW (fixture->tree_view), path,
-                      use_align, row_align);
-}
-
-static void
-scroll_both_no_align (ScrollFixture *fixture,
-                     gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll_both_realize (fixture, path, FALSE, 0.0);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_both_align_0_0 (ScrollFixture *fixture,
-                      gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll_both_realize (fixture, path, TRUE, 0.0);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_both_align_0_5 (ScrollFixture *fixture,
-                      gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll_both_realize (fixture, path, TRUE, 0.5);
-       gtk_tree_path_free (path);
-}
-
-static void
-scroll_both_align_1_0 (ScrollFixture *fixture,
-                      gconstpointer  test_data)
-{
-       GtkTreePath *path;
-
-       path = gtk_tree_path_new_from_string (test_data);
-       scroll_both_realize (fixture, path, TRUE, 1.0);
-       gtk_tree_path_free (path);
-}
-
-/* Testing scrolling to a newly created row */
-static void
-create_new_row (GtkListStore *store,
-               int           n,
-               GtkTreeIter  *iter)
-{
-       switch (n) {
-               case 0:
-                       /* Prepend a row */
-                       gtk_list_store_prepend (store, iter);
-                       break;
-
-                case 3:
-                       /* Add a row in the middle of the visible area */
-                       gtk_list_store_insert (store, iter, 3);
-                       break;
-
-               case 4:
-                       /* Add a row in the middle of the visible area */
-                       gtk_list_store_insert (store, iter, 4);
-                       break;
-
-                case 5:
-                       /* Add a row which is not completely visible */
-                       gtk_list_store_insert (store, iter, 5);
-                       break;
-
-               case 8:
-                       /* Add a row which is not completely visible */
-                       gtk_list_store_insert (store, iter, 8);
-                       break;
-
-               case 500:
-                       /* Add a row in the middle */
-                       gtk_list_store_insert (store, iter, 500);
-                       break;
-
-               case 999:
-                       /* Append a row */
-                       gtk_list_store_append (store, iter);
-                       break;
-       }
-
-       gtk_list_store_set (store, iter, 0, "New...", -1);
-}
-
-static void
-scroll_new_row_editing_started (GtkCellRenderer *cell,
-                               GtkCellEditable *editable,
-                               const char      *path,
-                               gpointer         user_data)
-{
-       GtkWidget **widget = user_data;
-
-       *widget = GTK_WIDGET (editable);
-}
-
-static void
-test_editable_position (GtkWidget   *tree_view,
-                       GtkWidget   *editable,
-                       GtkTreePath *cursor_path)
-{
-        GtkAllocation allocation;
-       GdkRectangle rect;
-
-       gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
-                                          cursor_path, NULL, &rect);
-
-       /* There are all in bin_window coordinates */
-        gtk_widget_get_allocation (editable, &allocation);
-        g_assert (allocation.y == rect.y + ((rect.height - allocation.height) / 2));
-}
-
-static void
-scroll_new_row (ScrollFixture *fixture,
-               gconstpointer  test_data)
-{
-       GtkTreeIter scroll_iter;
-       GtkTreePath *scroll_path;
-       GtkTreeModel *model;
-       GList *renderers;
-       GtkTreeViewColumn *column;
-       GtkWidget *editable;
-
-       /* The aim of this test is creating a new row at several places,
-        * and immediately put the cursor on it.  TreeView should correctly
-        * scroll to the row and show the editable widget.
-        *
-        * See #81627.
-        */
-
-       g_test_bug ("81627");
-
-       gtk_widget_show_all (fixture->window);
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       /* Create the new row and scroll to it */
-       model = gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view));
-       create_new_row (GTK_LIST_STORE (model), GPOINTER_TO_INT (test_data),
-                       &scroll_iter);
-
-       /* Set up a signal handler to acquire the editable widget */
-       column = gtk_tree_view_get_column (GTK_TREE_VIEW (fixture->tree_view), 0);
-       renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
-
-       g_signal_connect (G_OBJECT (renderers->data), "editing-started",
-                         G_CALLBACK (scroll_new_row_editing_started),
-                         &editable);
-
-       /* Now set the cursor on the path and start editing */
-       scroll_path = gtk_tree_model_get_path (model, &scroll_iter);
-       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view),
-                                 scroll_path,
-                                 column,
-                                 TRUE);
-
-        ensure_layout ();
-
-       /* Test position */
-       test_position (GTK_TREE_VIEW (fixture->tree_view), scroll_path,
-                      FALSE, 0.0);
-       test_editable_position (fixture->tree_view, editable, scroll_path);
-
-       gtk_tree_path_free (scroll_path);
-}
-
-static void
-scroll_new_row_tree (ScrollFixture *fixture,
-                    gconstpointer  test_data)
-{
-       GtkTreeModel *model;
-       GtkAdjustment *vadjustment;
-       int i;
-
-       /* The goal of this test is to append new rows at the end of a tree
-        * store and immediately scroll to them.  If there is a parent
-        * node with a couple of childs in the "area above" to explore,
-        * this used to lead to unexpected results due to a bug.
-        *
-        * This issue has been reported by Miroslav Rajcic on
-        * gtk-app-devel-list:
-        * http://mail.gnome.org/archives/gtk-app-devel-list/2008-December/msg00068.html
-        */
-
-       gtk_widget_show_all (fixture->window);
-
-       gtk_tree_view_expand_all (GTK_TREE_VIEW (fixture->tree_view));
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       model = gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view));
-       vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (fixture->tree_view));
-
-       for (i = 0; i < 5; i++) {
-               GtkTreeIter scroll_iter;
-               GtkTreePath *scroll_path;
-
-               gtk_tree_store_append (GTK_TREE_STORE (model), &scroll_iter,
-                                      NULL);
-               gtk_tree_store_set (GTK_TREE_STORE (model), &scroll_iter,
-                                   0, "New node", -1);
-
-               scroll_path = gtk_tree_model_get_path (model, &scroll_iter);
-               gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
-                                             scroll_path, NULL, FALSE, 0.0, 0.0);
-               gtk_tree_path_free (scroll_path);
-
-                ensure_layout ();
-
-               /* Test position, the scroll bar must be at the end */
-               g_assert (gtk_adjustment_get_value (vadjustment) == gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment));
-       }
-}
-
-/* Test for GNOME bugzilla bug 359231; tests "recovery when removing a bunch of
- * rows at the bottom.
- */
-static void
-test_bug316689 (ScrollFixture *fixture,
-               gconstpointer  test_data)
-{
-       GtkTreeIter iter;
-       GtkTreePath *path;
-       GtkAdjustment *vadjustment;
-       GtkTreeModel *model;
-
-       /* The aim of this test is to scroll to the bottom of a TreeView,
-        * remove at least one page_size of items and check if TreeView
-        * correctly corrects the scroll bar (else they will look "broken").
-        *
-        * See #316689.
-        */
-
-       g_test_bug ("316689");
-
-       /* Scroll to some place close to the end */
-       path = gtk_tree_path_new_from_indices (N_ROWS - 4, -1);
-       scroll (fixture, path, FALSE, 0.0);
-       gtk_tree_path_free (path);
-
-       /* No need for a while events pending loop here, scroll() does this for us.
-        *
-        * We now remove a bunch of rows, wait for events to process and then
-        * check the adjustments to see if the TreeView gracefully recovered.
-        */
-       model = gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view));
-
-       while (gtk_tree_model_iter_nth_child (model, &iter, NULL, N_ROWS - 15))
-               gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (fixture->tree_view));
-
-       g_assert (gtk_adjustment_get_value (vadjustment) + gtk_adjustment_get_page_size (vadjustment) <= gtk_adjustment_get_upper (vadjustment));
-       g_assert (gtk_adjustment_get_value (vadjustment) == gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment));
-}
-
-
-/* Test for GNOME bugzilla bug 359231 */
-static void
-test_bug359231 (void)
-{
-       int i;
-       int height1, height2;
-       GtkTreePath *path;
-       GtkTreeIter iter, child;
-       GtkTreeStore *store;
-       GdkRectangle rect;
-       ScrollFixture *fixture;
-
-       /* See #359231. */
-       g_test_bug ("359231");
-
-       /* Create model (GtkTreeStore in this case) */
-       store = gtk_tree_store_new (1, G_TYPE_STRING);
-
-       gtk_tree_store_append (store, &iter, NULL);
-       gtk_tree_store_set (store, &iter, 0, "Foo", -1);
-
-       for (i = 0; i < 4; i++) {
-               gtk_tree_store_append (store, &child, &iter);
-               gtk_tree_store_set (store, &child, 0, "Two\nLines", -1);
-       }
-       
-       fixture = g_new0 (ScrollFixture, 1);
-       scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), NULL);
-       gtk_widget_show_all (fixture->window);
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       /* Prepend some rows at the top, expand */
-       gtk_tree_store_prepend (store, &iter, NULL);
-       gtk_tree_store_set (store, &iter, 0, "Foo", -1);
-
-       gtk_tree_store_prepend (store, &child, &iter);
-       gtk_tree_store_set (store, &child, 0, "Two\nLines", -1);
-
-       gtk_tree_view_expand_all (GTK_TREE_VIEW (fixture->tree_view));
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       /* Test if height of row 0:0 is correct */
-       path = gtk_tree_path_new_from_indices (0, -1);
-       gtk_tree_view_get_background_area (GTK_TREE_VIEW (fixture->tree_view),
-                                          path, NULL, &rect);
-       height1 = rect.height;
-
-       gtk_tree_path_down (path);
-       gtk_tree_view_get_background_area (GTK_TREE_VIEW (fixture->tree_view),
-                                          path, NULL, &rect);
-       height2 = rect.height;
-       gtk_tree_path_free (path);
-
-       g_assert (height2 > height1);
-
-       /* Clean up; the tear down also cleans up the model */
-       scroll_fixture_teardown (fixture, NULL);
-}
-
-/* Test for GNOME bugzilla bug 93584.  We add 150 rows to an existing
- * small model, and scroll to one of these with alignment.
- */
-static void
-test_bug93584 (ScrollFixture *fixture,
-              gconstpointer  test_data)
-{
-       int row, i;
-       GtkTreeStore *store;
-       GtkTreePath *path;
-
-       g_test_bug ("93584");
-
-       /* Mimic state as in original test case */
-       g_signal_connect (G_OBJECT (fixture->tree_view), "realize",
-                         G_CALLBACK (gtk_tree_view_expand_all), NULL);
-       gtk_widget_show_all (fixture->window);
-
-       store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
-
-       /* Add 150 rows */
-       for (i = 0; i < 150; i++) {
-               GtkTreeIter iter;
-
-               gtk_tree_store_append (store, &iter, NULL);
-               gtk_tree_store_set (store, &iter, 0, "Row", -1);
-       }
-
-       row = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
-       row -= 20;
-
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       path = gtk_tree_path_new_from_indices (row, -1);
-       scroll (fixture, path, TRUE, 0.5);
-       gtk_tree_path_free (path);
-}
-
-/* GNOME bugzilla bug 111500.  Expand a row and immediately scroll
- * to its first child.  Make sure that expansion happens in currently
- * invisible area.
- */
-static void
-test_bug111500 (ScrollFixture *fixture,
-               gconstpointer  test_data)
-{
-       int i, len;
-       GtkTreeStore *store;
-       GtkTreeIter parent;
-       GtkTreePath *path;
-
-       g_test_bug ("111500");
-
-       gtk_widget_show_all (fixture->window);
-
-       /* Make sure all events have been processed and the window
-        * is visible.
-        */
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       /* Further prepare model */
-       store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
-
-       for (i = 0; i < 15; i++) {
-               GtkTreeIter iter;
-
-               gtk_tree_store_append (store, &iter, NULL);
-               gtk_tree_store_set (store, &iter, 0, "Other node", -1);
-       }
-
-       len = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
-       gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &parent,
-                                      NULL, len - 1);
-
-       for (i = 0; i < 5; i++) {
-               GtkTreeIter iter;
-
-               gtk_tree_store_append (store, &iter, &parent);
-               gtk_tree_store_set (store, &iter, 0, "Row", -1);
-       }
-
-       path = gtk_tree_path_new_from_indices (len - 1, -1);
-       gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view),
-                                 path, FALSE);
-
-       gtk_tree_path_down (path);
-
-       scroll (fixture, path, FALSE, 0.5);
-       gtk_tree_path_free (path);
-}
-
-static void
-test_bug111500_mixed (ScrollFixture *fixture,
-                     gconstpointer  test_data)
-{
-       int i, len;
-       GtkTreeStore *store;
-       GtkTreeIter parent;
-       GtkTreePath *path;
-
-       g_test_bug ("111500");
-
-       gtk_widget_show_all (fixture->window);
-
-       /* Make sure all events have been processed and the window
-        * is visible.
-        */
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       /* Further prepare model */
-       store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
-
-       for (i = 0; i < 15; i++) {
-               GtkTreeIter iter;
-
-               gtk_tree_store_append (store, &iter, NULL);
-               if (i % 2 == 0)
-                       gtk_tree_store_set (store, &iter, 0, "Other node", -1);
-               else
-                       gtk_tree_store_set (store, &iter, 0, "Other\nnode", -1);
-       }
-
-       len = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
-       gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &parent,
-                                      NULL, len - 1);
-
-       for (i = 0; i < 5; i++) {
-               GtkTreeIter iter;
-
-               gtk_tree_store_append (store, &iter, &parent);
-               if (i % 2 != 0)
-                       gtk_tree_store_set (store, &iter, 0, "Row", -1);
-               else
-                       gtk_tree_store_set (store, &iter, 0, "Row\nRow", -1);
-       }
-
-       path = gtk_tree_path_new_from_indices (len - 1, -1);
-       gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view),
-                                 path, FALSE);
-
-       gtk_tree_path_down (path);
-
-       scroll (fixture, path, FALSE, 0.5);
-       gtk_tree_path_free (path);
-}
-
-/* Test for GNOME bugzilla bug 163214.  Invalidate a couple of rows,
- * then scroll to one of these.
- */
-static void
-test_bug163214 (ScrollFixture *fixture,
-               gconstpointer  test_data)
-{
-       int i;
-       GtkListStore *store;
-       GtkTreePath *path;
-
-       g_test_bug ("163214");
-
-       gtk_widget_show_all (fixture->window);
-
-       /* Make sure all events have been processed and the window
-        * is visible.
-        */
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
-
-       /* Invalidate a page of rows */
-       for (i = 100; i < 110; i++) {
-               GtkTreeIter iter;
-
-               gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter,
-                                              NULL, i);
-               gtk_list_store_set (store, &iter, 0, "Row", -1);
-       }
-
-       /* Then scroll to that page. */
-       path = gtk_tree_path_new_from_indices (105, -1);
-       scroll (fixture, path, TRUE, 0.5);
-       gtk_tree_path_free (path);
-
-       /* Make sure all events have been processed and the window
-        * is visible.
-        */
-       while (gtk_events_pending ())
-               gtk_main_iteration ();
-
-       store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
-
-       /* Invalidate a page of rows */
-       for (i = 300; i < 310; i++) {
-               GtkTreeIter iter;
-
-               gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter,
-                                              NULL, i);
-               gtk_list_store_set (store, &iter, 0, "Row", -1);
-       }
-
-       /* Then scroll to the first row */
-       path = gtk_tree_path_new_from_indices (0, -1);
-       scroll (fixture, path, TRUE, 0.5);
-       gtk_tree_path_free (path);
-}
-
-/* Infrastructure for automatically adding tests */
-enum
-{
-       BEFORE,
-       AFTER,
-       BOTH
-};
-
-static const char *
-test_type_string (int test_type)
-{
-       switch (test_type) {
-               case BEFORE:
-                       return "before-realize";
-
-               case AFTER:
-                       return "after-realize";
-
-               case BOTH:
-                       return "both";
-       }
-
-       return "???";
-}
-
-static char *
-align_string (gboolean use_align,
-             gdouble  row_align)
-{
-       char *ret;
-
-       if (!use_align)
-               return g_strdup ("no-align");
-
-       ret = g_strdup_printf ("align-%1.1f", row_align);
-       return ret;
-}
-
-static void
-add_test (const char *path,
-         gboolean    mixed,
-         int         test_type,
-         gboolean    use_align,
-         gdouble     row_align,
-         void (* setup) (ScrollFixture *, gconstpointer),
-         void (* scroll_func) (ScrollFixture *, gconstpointer))
-{
-       gchar *test_path;
-       gchar *align;
-
-       align = align_string (use_align, row_align);
-
-       test_path = g_strdup_printf ("/TreeView/scrolling/%s/%s-height/path-%s-%s",
-                                    test_type_string (test_type),
-                                    mixed ? "mixed" : "constant",
-                                    path, align);
-       g_free (align);
-
-       g_test_add (test_path, ScrollFixture, path,
-                   setup, scroll_func, scroll_fixture_teardown);
-
-       g_free (test_path);
-}
-
-static void
-add_tests (gboolean mixed,
-          int test_type,
-          gboolean use_align,
-          gdouble  row_align,
-          void (*scroll_func) (ScrollFixture *, gconstpointer))
-{
-       void (* setup) (ScrollFixture *, gconstpointer);
-
-       if (mixed)
-               setup = scroll_fixture_mixed_setup;
-       else
-               setup = scroll_fixture_constant_setup;
-
-       add_test ("0", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("2", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("5", mixed, test_type, use_align, row_align, setup, scroll_func);
-       /* We scroll to 8 to test a partial visible row.  The 8 is
-        * based on my font setting of "Vera Sans 11" and
-        * the separators set to 0.  (This should be made dynamic; FIXME).
-        */
-       add_test ("8", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("10", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("250", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("500", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("750", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("990", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("991", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("995", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("997", mixed, test_type, use_align, row_align, setup, scroll_func);
-       add_test ("999", mixed, test_type, use_align, row_align, setup, scroll_func);
-}
-
-int
-main (int argc, char **argv)
-{
-       gtk_test_init (&argc, &argv);
-
-       /* Scrolls before realization */
-       add_tests (FALSE, BEFORE, FALSE, 0.0, scroll_no_align);
-       if (g_test_thorough ())
-               add_tests (TRUE, BEFORE, FALSE, 0.0, scroll_no_align);
-
-       add_tests (FALSE, BEFORE, TRUE, 0.0, scroll_align_0_0);
-       if (g_test_thorough ())
-               add_tests (TRUE, BEFORE, TRUE, 0.0, scroll_align_0_0);
-
-       add_tests (FALSE, BEFORE, TRUE, 0.5, scroll_align_0_5);
-       if (g_test_thorough ())
-               add_tests (TRUE, BEFORE, TRUE, 0.5, scroll_align_0_5);
-
-       add_tests (FALSE, BEFORE, TRUE, 1.0, scroll_align_1_0);
-       if (g_test_thorough ())
-               add_tests (TRUE, BEFORE, TRUE, 1.0, scroll_align_1_0);
-
-       /* Scrolls after realization */
-       add_tests (FALSE, AFTER, FALSE, 0.0, scroll_after_no_align);
-       if (g_test_thorough ())
-               add_tests (TRUE, AFTER, FALSE, 0.0, scroll_after_no_align);
-
-       add_tests (FALSE, AFTER, TRUE, 0.0, scroll_after_align_0_0);
-       if (g_test_thorough ())
-               add_tests (TRUE, AFTER, TRUE, 0.0, scroll_after_align_0_0);
-
-       add_tests (FALSE, AFTER, TRUE, 0.5, scroll_after_align_0_5);
-       if (g_test_thorough ())
-               add_tests (TRUE, AFTER, TRUE, 0.5, scroll_after_align_0_5);
-
-       add_tests (FALSE, AFTER, TRUE, 1.0, scroll_after_align_1_0);
-       if (g_test_thorough ())
-               add_tests (TRUE, AFTER, TRUE, 1.0, scroll_after_align_1_0);
-
-       /* Scroll to end before realization, to a real position after */
-       if (g_test_thorough ()) {
-               add_tests (FALSE, BOTH, FALSE, 0.0, scroll_both_no_align);
-               add_tests (TRUE, BOTH, FALSE, 0.0, scroll_both_no_align);
-
-               add_tests (FALSE, BOTH, TRUE, 0.0, scroll_both_align_0_0);
-               add_tests (TRUE, BOTH, TRUE, 0.0, scroll_both_align_0_0);
-
-               add_tests (FALSE, BOTH, TRUE, 0.5, scroll_both_align_0_5);
-               add_tests (TRUE, BOTH, TRUE, 0.5, scroll_both_align_0_5);
-
-               add_tests (FALSE, BOTH, TRUE, 1.0, scroll_both_align_1_0);
-               add_tests (TRUE, BOTH, TRUE, 1.0, scroll_both_align_1_0);
-       }
-
-       /* Test different alignments in view with single row */
-       g_test_add ("/TreeView/scrolling/single-row/no-align",
-                   ScrollFixture, "0",
-                   scroll_fixture_single_setup,
-                   scroll_no_align,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/single-row/align-0.0",
-                   ScrollFixture, "0",
-                   scroll_fixture_single_setup,
-                   scroll_align_0_0,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/single-row/align-0.5",
-                   ScrollFixture, "0",
-                   scroll_fixture_single_setup,
-                   scroll_align_0_5,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/single-row/align-1.0",
-                   ScrollFixture, "0",
-                   scroll_fixture_single_setup,
-                   scroll_align_1_0,
-                   scroll_fixture_teardown);
-
-       /* Test scrolling in a very large model; also very slow */
-       if (g_test_slow ()) {
-               g_test_add ("/TreeView/scrolling/large-model/constant-height/middle-no-align",
-                           ScrollFixture, "50000",
-                           scroll_fixture_constant_big_setup,
-                           scroll_no_align,
-                           scroll_fixture_teardown);
-               g_test_add ("/TreeView/scrolling/large-model/constant-height/end-no-align",
-                           ScrollFixture, "99999",
-                           scroll_fixture_constant_big_setup,
-                           scroll_no_align,
-                           scroll_fixture_teardown);
-
-               g_test_add ("/TreeView/scrolling/large-model/mixed-height/middle-no-align",
-                           ScrollFixture, "50000",
-                           scroll_fixture_mixed_big_setup,
-                           scroll_no_align,
-                           scroll_fixture_teardown);
-               g_test_add ("/TreeView/scrolling/large-model/mixed-height/end-no-align",
-                           ScrollFixture, "99999",
-                           scroll_fixture_mixed_big_setup,
-                           scroll_no_align,
-                           scroll_fixture_teardown);
-       }
-
-       /* Test scrolling to a newly created row */
-       g_test_add ("/TreeView/scrolling/new-row/path-0", ScrollFixture,
-                   GINT_TO_POINTER (0),
-                   scroll_fixture_constant_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/new-row/path-4", ScrollFixture,
-                   GINT_TO_POINTER (4),
-                   scroll_fixture_constant_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-       /* We scroll to 8 to test a partial visible row.  The 8 is
-        * based on my font setting of "Vera Sans 11" and
-        * the separators set to 0.  (This should be made dynamic; FIXME).
-        */
-       g_test_add ("/TreeView/scrolling/new-row/path-8", ScrollFixture,
-                   GINT_TO_POINTER (8),
-                   scroll_fixture_constant_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/new-row/path-500", ScrollFixture,
-                   GINT_TO_POINTER (500),
-                   scroll_fixture_constant_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/new-row/path-999", ScrollFixture,
-                   GINT_TO_POINTER (999),
-                   scroll_fixture_constant_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-
-       g_test_add ("/TreeView/scrolling/new-row/tree", ScrollFixture,
-                   NULL,
-                   scroll_fixture_tree_setup,
-                   scroll_new_row_tree,
-                   scroll_fixture_teardown);
-
-       /* Test scrolling to a newly created row, in a mixed height model */
-       g_test_add ("/TreeView/scrolling/new-row-mixed/path-0", ScrollFixture,
-                   GINT_TO_POINTER (0),
-                   scroll_fixture_mixed_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/new-row-mixed/path-3", ScrollFixture,
-                   GINT_TO_POINTER (3),
-                   scroll_fixture_mixed_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-       /* We scroll to 8 to test a partial visible row.  The 8 is
-        * based on my font setting of "Vera Sans 11" and
-        * the separators set to 0.  (This should be made dynamic; FIXME).
-        */
-       g_test_add ("/TreeView/scrolling/new-row-mixed/path-5", ScrollFixture,
-                   GINT_TO_POINTER (5),
-                   scroll_fixture_mixed_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/new-row-mixed/path-500", ScrollFixture,
-                   GINT_TO_POINTER (500),
-                   scroll_fixture_mixed_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/new-row-mixed/path-999", ScrollFixture,
-                   GINT_TO_POINTER (999),
-                   scroll_fixture_mixed_setup,
-                   scroll_new_row,
-                   scroll_fixture_teardown);
-
-       g_test_add ("/TreeView/scrolling/new-row-mixed/tree", ScrollFixture,
-                   NULL,
-                   scroll_fixture_mixed_tree_setup,
-                   scroll_new_row_tree,
-                   scroll_fixture_teardown);
-
-       /* Misc. tests */
-       g_test_add ("/TreeView/scrolling/specific/bug-316689",
-                       ScrollFixture, NULL,
-                   scroll_fixture_constant_setup, test_bug316689,
-                   scroll_fixture_teardown);
-       g_test_add_func ("/TreeView/scrolling/specific/bug-359231",
-                       test_bug359231);
-       g_test_add ("/TreeView/scrolling/specific/bug-93584",
-                   ScrollFixture, NULL,
-                   scroll_fixture_tree_setup, test_bug93584,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/specific/bug-111500",
-                   ScrollFixture, NULL,
-                   scroll_fixture_tree_setup, test_bug111500,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/specific/bug-111500-mixed",
-                   ScrollFixture, NULL,
-                   scroll_fixture_mixed_tree_setup, test_bug111500_mixed,
-                   scroll_fixture_teardown);
-       g_test_add ("/TreeView/scrolling/specific/bug-163214",
-                   ScrollFixture, NULL,
-                   scroll_fixture_constant_setup, test_bug163214,
-                   scroll_fixture_teardown);
-
-       return g_test_run ();
-}
diff --git a/gtk/tests/treeview.c b/gtk/tests/treeview.c
deleted file mode 100644 (file)
index 34676a5..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/* Basic GtkTreeView unit tests.
- * Copyright (C) 2009  Kristian Rietveld  <kris@gtk.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-static void
-test_bug_546005 (void)
-{
-  GtkTreeIter iter;
-  GtkTreePath *path;
-  GtkTreePath *cursor_path;
-  GtkListStore *list_store;
-  GtkWidget *view;
-
-  /* Tests provided by Bjorn Lindqvist, Paul Pogonyshev */
-  view = gtk_tree_view_new ();
-
-  /* Invalid path on tree view without model */
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
-                            NULL, FALSE);
-  gtk_tree_path_free (path);
-
-  list_store = gtk_list_store_new (1, G_TYPE_STRING);
-  gtk_tree_view_set_model (GTK_TREE_VIEW (view),
-                           GTK_TREE_MODEL (list_store));
-
-  /* Invalid path on tree view with empty model */
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
-                            NULL, FALSE);
-  gtk_tree_path_free (path);
-
-  /* Valid path */
-  gtk_list_store_insert_with_values (list_store, &iter, 0,
-                                     0, "hi",
-                                     -1);
-
-  path = gtk_tree_path_new_from_indices (0, -1);
-  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
-                            NULL, FALSE);
-
-  gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &cursor_path, NULL);
-  //gtk_assert_cmptreepath (cursor_path, ==, path);
-
-  gtk_tree_path_free (path);
-  gtk_tree_path_free (cursor_path);
-
-  /* Invalid path on tree view with model */
-  path = gtk_tree_path_new_from_indices (1, -1);
-  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
-                            NULL, FALSE);
-  gtk_tree_path_free (path);
-}
-
-static void
-test_bug_539377 (void)
-{
-  GtkWidget *view;
-  GtkTreePath *path;
-  GtkListStore *list_store;
-
-  /* Test provided by Bjorn Lindqvist */
-
-  /* Non-realized view, no model */
-  view = gtk_tree_view_new ();
-  g_assert (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), 10, 10, &path,
-                                           NULL, NULL, NULL) == FALSE);
-  g_assert (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), 10, 10,
-                                               &path, NULL) == FALSE);
-
-  /* Non-realized view, with model */
-  list_store = gtk_list_store_new (1, G_TYPE_STRING);
-  gtk_tree_view_set_model (GTK_TREE_VIEW (view),
-                           GTK_TREE_MODEL (list_store));
-
-  g_assert (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), 10, 10, &path,
-                                           NULL, NULL, NULL) == FALSE);
-  g_assert (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), 10, 10,
-                                               &path, NULL) == FALSE);
-}
-
-static void
-test_select_collapsed_row (void)
-{
-  GtkTreeIter child, parent;
-  GtkTreePath *path;
-  GtkTreeStore *tree_store;
-  GtkTreeSelection *selection;
-  GtkWidget *view;
-
-  /* Reported by Michael Natterer */
-  tree_store = gtk_tree_store_new (1, G_TYPE_STRING);
-  view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
-
-  gtk_tree_store_insert_with_values (tree_store, &parent, NULL, 0,
-                                     0, "Parent",
-                                     -1);
-
-  gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0,
-                                     0, "Child",
-                                     -1);
-  gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0,
-                                     0, "Child",
-                                     -1);
-
-
-  /* Try to select a child path. */
-  path = gtk_tree_path_new_from_indices (0, 1, -1);
-  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
-
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
-
-  /* Check that the parent is not selected. */
-  gtk_tree_path_up (path);
-  g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == FALSE);
-
-  /* Nothing should be selected at this point. */
-  g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 0);
-
-  /* Check that selection really still works. */
-  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
-  g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE);
-  g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
-
-  /* Expand and select child node now. */
-  gtk_tree_path_append_index (path, 1);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
-
-  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
-  g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE);
-  g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
-
-  gtk_tree_path_free (path);
-}
-
-static gboolean
-test_row_separator_height_func (GtkTreeModel *model,
-                                GtkTreeIter  *iter,
-                                gpointer      data)
-{
-  gboolean ret = FALSE;
-  GtkTreePath *path;
-
-  path = gtk_tree_model_get_path (model, iter);
-  if (gtk_tree_path_get_indices (path)[0] == 2)
-    ret = TRUE;
-  gtk_tree_path_free (path);
-
-  return ret;
-}
-
-static void
-test_row_separator_height (void)
-{
-  int focus_pad, separator_height, height;
-  gboolean wide_separators;
-  GtkTreeIter iter;
-  GtkTreePath *path;
-  GtkListStore *store;
-  GtkWidget *window;
-  GtkWidget *tree_view;
-  GdkRectangle rect, cell_rect;
-
-  store = gtk_list_store_new (1, G_TYPE_STRING);
-  gtk_list_store_insert_with_values (store, &iter, 0, 0, "Row content", -1);
-  gtk_list_store_insert_with_values (store, &iter, 1, 0, "Row content", -1);
-  gtk_list_store_insert_with_values (store, &iter, 2, 0, "Row content", -1);
-  gtk_list_store_insert_with_values (store, &iter, 3, 0, "Row content", -1);
-  gtk_list_store_insert_with_values (store, &iter, 4, 0, "Row content", -1);
-
-  window = gtk_offscreen_window_new ();
-
-  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
-  gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (tree_view),
-                                        test_row_separator_height_func,
-                                        NULL,
-                                        NULL);
-
-  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
-                                               0,
-                                               "Test",
-                                               gtk_cell_renderer_text_new (),
-                                               "text", 0,
-                                               NULL);
-
-  gtk_container_add (GTK_CONTAINER (window), tree_view);
-  gtk_widget_show_all (window);
-
-
-  path = gtk_tree_path_new_from_indices (2, -1);
-  gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
-                                     path, NULL, &rect);
-  gtk_tree_view_get_cell_area (GTK_TREE_VIEW (tree_view),
-                               path, NULL, &cell_rect);
-  gtk_tree_path_free (path);
-
-  gtk_widget_style_get (tree_view,
-                        "focus-padding", &focus_pad,
-                        "wide-separators", &wide_separators,
-                        "separator-height", &separator_height,
-                        NULL);
-
-  if (wide_separators)
-    height = separator_height + 2 * focus_pad;
-  else
-    height = 2 + 2 * focus_pad;
-
-  g_assert_cmpint (rect.height, ==, height);
-  g_assert_cmpint (cell_rect.height, ==, height);
-
-  gtk_widget_destroy (tree_view);
-}
-
-int
-main (int    argc,
-      char **argv)
-{
-  gtk_test_init (&argc, &argv, NULL);
-
-  g_test_add_func ("/TreeView/cursor/bug-546005", test_bug_546005);
-  g_test_add_func ("/TreeView/cursor/bug-539377", test_bug_539377);
-  g_test_add_func ("/TreeView/cursor/select-collapsed_row",
-                   test_select_collapsed_row);
-  g_test_add_func ("/TreeView/sizing/row-separator-height",
-                   test_row_separator_height);
-
-  return g_test_run ();
-}
diff --git a/gtk/tests/window.c b/gtk/tests/window.c
deleted file mode 100644 (file)
index 74fa6eb..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-#include <gtk/gtk.h>
-
-static gboolean interactive = FALSE;
-
-static gboolean
-stop_main (gpointer data)
-{
-  gtk_main_quit ();
-
-  return G_SOURCE_REMOVE;
-}
-
-static gboolean
-on_draw (GtkWidget *widget, cairo_t *cr)
-{
-  gint i, j;
-
-  for (i = 0; 20 * i < gtk_widget_get_allocated_width (widget); i++)
-    {
-      for (j = 0; 20 * j < gtk_widget_get_allocated_height (widget); j++)
-        {
-          if ((i + j) % 2 == 1)
-            cairo_set_source_rgb (cr, 1., 1., 1.);
-          else
-            cairo_set_source_rgb (cr, 0., 0., 0.);
-
-          cairo_rectangle (cr, 20. * i, 20. *j, 20., 20.);
-          cairo_fill (cr);
-        }
-    }
-
-  return FALSE;
-}
-
-static gboolean
-on_keypress (GtkWidget *widget)
-{
-  gtk_main_quit ();
-
-  return TRUE;
-}
-
-static void
-test_default_size (void)
-{
-  GtkWidget *window;
-  GtkWidget *box;
-  gint w, h;
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  g_signal_connect (window, "draw", G_CALLBACK (on_draw), NULL);
-  if (interactive)
-    g_signal_connect (window, "key-press-event", G_CALLBACK (on_keypress), NULL);
-
-  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-  gtk_container_add (GTK_CONTAINER (window), box);
-
-  /* check that default size is unset initially */
-  gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, -1);
-  g_assert_cmpint (h, ==, -1);
-
-  /* check that setting default size before realize works */
-  gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
-
-  gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 300);
-  g_assert_cmpint (h, ==, 300);
-
-  /* check that the window size is also reported accordingly */
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 300);
-  g_assert_cmpint (h, ==, 300);
-
-  gtk_widget_show_all (window);
-
-  if (!interactive)
-    g_timeout_add (200, stop_main, NULL);
-  gtk_main ();
-
-  /* check that the window and its content actually gets the right size */
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 300);
-  g_assert_cmpint (h, ==, 300);
-
-  g_assert_cmpint (gtk_widget_get_allocated_width (window), ==, 300);
-  g_assert_cmpint (gtk_widget_get_allocated_height (window), ==, 300);
-
-  g_assert_cmpint (gtk_widget_get_allocated_width (box), ==, 300);
-  g_assert_cmpint (gtk_widget_get_allocated_height (box), ==, 300);
-
-  /* check that setting default size after the fact does not change
-   * window size
-   */
-  gtk_window_set_default_size (GTK_WINDOW (window), 100, 600);
-  gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 100);
-  g_assert_cmpint (h, ==, 600);
-
-  if (!interactive)
-    g_timeout_add (200, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 300);
-  g_assert_cmpint (h, ==, 300);
-
-  /* check that even hide/show does not pull in the new default */
-  gtk_widget_hide (window);
-  gtk_widget_show (window);
-
-  if (!interactive)
-    g_timeout_add (200, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 300);
-  g_assert_cmpint (h, ==, 300);
-
-  gtk_widget_destroy (window);
-}
-
-static void
-test_resize (void)
-{
-  GtkWidget *window;
-  GtkWidget *box;
-  gint w, h;
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  g_signal_connect (window, "draw", G_CALLBACK (on_draw), NULL);
-  if (interactive)
-    g_signal_connect (window, "key-press-event", G_CALLBACK (on_keypress), NULL);
-
-  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-  gtk_container_add (GTK_CONTAINER (window), box);
-
-  /* test that resize before show overrides default size */
-  gtk_window_set_default_size (GTK_WINDOW (window), 500, 500);
-
-  gtk_window_resize (GTK_WINDOW (window), 1, 1);
-
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 1);
-  g_assert_cmpint (h, ==, 1);
-
-  gtk_window_resize (GTK_WINDOW (window), 400, 200);
-
-  gtk_widget_show_all (window);
-
-  if (!interactive)
-    g_timeout_add (200, stop_main, NULL);
-  gtk_main ();
-
-  /* test that resize before show works */
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 400);
-  g_assert_cmpint (h, ==, 200);
-
-  /* test that resize after show works, both
-   * for making things bigger and for making things
-   * smaller
-   */
-  gtk_window_resize (GTK_WINDOW (window), 200, 400);
-
-  if (!interactive)
-    g_timeout_add (200, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (w, ==, 200);
-  g_assert_cmpint (h, ==, 400);
-
-  gtk_widget_destroy (window);
-}
-
-static void
-test_resize_popup (void)
-{
-  GtkWidget *window;
-  gint x, y, w, h;
-
-  /* testcase for the dnd window */
-  window = gtk_window_new (GTK_WINDOW_POPUP);
-  gtk_window_set_screen (GTK_WINDOW (window), gdk_screen_get_default ());
-  gtk_window_resize (GTK_WINDOW (window), 1, 1);
-  gtk_window_move (GTK_WINDOW (window), -99, -99);
-
-  gtk_window_get_position (GTK_WINDOW (window), &x, &y);
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (x, ==, -99);
-  g_assert_cmpint (y, ==, -99);
-  g_assert_cmpint (w, ==, 1);
-  g_assert_cmpint (h, ==, 1);
-
-  gtk_widget_show (window);
-
-  g_timeout_add (200, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_position (GTK_WINDOW (window), &x, &y);
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  g_assert_cmpint (x, ==, -99);
-  g_assert_cmpint (y, ==, -99);
-  g_assert_cmpint (w, ==, 1);
-  g_assert_cmpint (h, ==, 1);
-
-  gtk_widget_destroy (window);
-}
-
-static void
-test_show_hide (void)
-{
-  GtkWidget *window;
-  gint w, h, w1, h1;
-
-  g_test_bug ("696882");
-
-  /* test that hide/show does not affect the size */
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
-  gtk_widget_show (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-
-  gtk_widget_hide (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
-  g_assert_cmpint (w, ==, w1);
-  g_assert_cmpint (h, ==, h1);
-
-  gtk_widget_show (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
-  g_assert_cmpint (w, ==, w1);
-  g_assert_cmpint (h, ==, h1);
-
-  gtk_widget_destroy (window);
-}
-
-static void
-test_show_hide2 (void)
-{
-  GtkWidget *window;
-  gint x, y, w, h, w1, h1;
-
-  g_test_bug ("696882");
-
-  /* test that hide/show does not affect the size,
-   * even when get_position/move is called
-   */
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
-  gtk_widget_show (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_position (GTK_WINDOW (window), &x, &y);
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  gtk_widget_hide (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
-  g_assert_cmpint (w, ==, w1);
-  g_assert_cmpint (h, ==, h1);
-
-  gtk_window_move (GTK_WINDOW (window), x, y);
-  gtk_widget_show (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
-  g_assert_cmpint (w, ==, w1);
-  g_assert_cmpint (h, ==, h1);
-
-  gtk_widget_destroy (window);
-}
-
-static void
-test_show_hide3 (void)
-{
-  GtkWidget *window;
-  gint x, y, w, h, w1, h1;
-
-  g_test_bug ("696882");
-
-  /* test that hide/show does not affect the size,
-   * even when get_position/move is called and
-   * a default size is set
-   */
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
-
-  gtk_widget_show (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_position (GTK_WINDOW (window), &x, &y);
-  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-  gtk_widget_hide (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
-  g_assert_cmpint (w, ==, w1);
-  g_assert_cmpint (h, ==, h1);
-
-  gtk_window_move (GTK_WINDOW (window), x, y);
-  gtk_widget_show (window);
-
-  g_timeout_add (100, stop_main, NULL);
-  gtk_main ();
-
-  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
-  g_assert_cmpint (w, ==, w1);
-  g_assert_cmpint (h, ==, h1);
-
-  gtk_widget_destroy (window);
-}
-
-int
-main (int argc, char *argv[])
-{
-  gint i;
-
-  gtk_test_init (&argc, &argv);
-  g_test_bug_base ("http://bugzilla.gnome.org/");
-
-  for (i = 0; i < argc; i++)
-    {
-      if (g_strcmp0 (argv[i], "--interactive") == 0)
-        interactive = TRUE;
-    }
-
-  g_test_add_func ("/window/default-size", test_default_size);
-  g_test_add_func ("/window/resize", test_resize);
-  g_test_add_func ("/window/resize-popup", test_resize_popup);
-  g_test_add_func ("/window/show-hide", test_show_hide);
-  g_test_add_func ("/window/show-hide2", test_show_hide2);
-  g_test_add_func ("/window/show-hide3", test_show_hide3);
-
-  return g_test_run ();
-}
index af7953b92a7e598ff8c85cbaaaecca31038ae83c..11f7e79c9e0236cf107d967f60fccebd673d87c7 100644 (file)
@@ -1,6 +1,6 @@
 include $(top_srcdir)/Makefile.decl
 
-SUBDIRS = gdk
+SUBDIRS = gdk gtk
 
 -include $(top_srcdir)/git.mk
 
diff --git a/testsuite/gtk/Makefile.am b/testsuite/gtk/Makefile.am
new file mode 100644 (file)
index 0000000..ea5b759
--- /dev/null
@@ -0,0 +1,192 @@
+include $(top_srcdir)/Makefile.decl
+
+SUBDIRS =
+
+AM_CPPFLAGS = \
+       -I$(top_srcdir)                 \
+       -I$(top_builddir)/gdk           \
+       -I$(top_srcdir)/gdk             \
+       -I$(top_builddir)/gtk           \
+       -I$(top_srcdir)/gtk             \
+       -DSRCDIR=\""$(abs_srcdir)"\"    \
+       $(GTK_DEBUG_FLAGS)              \
+       $(GTK_DEP_CFLAGS)
+
+if OS_UNIX
+AM_CPPFLAGS += -DHAVE_UNIX_PRINT_WIDGETS
+endif
+
+DEPS = \
+       $(top_builddir)/gtk/libgtk-3.la
+
+progs_ldadd = \
+       $(top_builddir)/gtk/libgtk-3.la \
+       $(top_builddir)/gdk/libgdk-3.la \
+       $(GTK_DEP_LIBS)
+
+noinst_PROGRAMS = $(TEST_PROGS)
+
+
+TEST_PROGS                     += testing
+testing_SOURCES                         = testing.c
+testing_LDADD                   = $(progs_ldadd)
+
+TEST_PROGS                     += treemodel
+treemodel_SOURCES               = \
+                               treemodel.h \
+                               treemodel.c \
+                               liststore.c \
+                               treestore.c \
+                               filtermodel.c \
+                               sortmodel.c \
+                               modelrefcount.c \
+                               gtktreemodelrefcount.h \
+                               gtktreemodelrefcount.c
+treemodel_LDADD                         = $(progs_ldadd)
+
+TEST_PROGS                     += treeview
+treeview_SOURCES                = treeview.c
+treeview_LDADD                  = $(progs_ldadd)
+
+TEST_PROGS                     += treeview-scrolling
+treeview_scrolling_SOURCES      = treeview-scrolling.c
+treeview_scrolling_LDADD        = $(progs_ldadd) -lm
+
+TEST_PROGS                     += recentmanager
+recentmanager_SOURCES           = recentmanager.c
+recentmanager_LDADD             = $(progs_ldadd)
+
+TEST_PROGS                     += floating
+floating_SOURCES                = floating.c
+floating_LDADD                  = $(progs_ldadd)
+
+TEST_PROGS                     += accel
+accel_SOURCES                   = accel.c
+accel_LDADD                     = $(progs_ldadd)
+
+#TEST_PROGS                    += object
+#object_SOURCES                         = object.c
+#object_LDADD                   = $(progs_ldadd)
+
+# this doesn't work in make distcheck, since running
+# on a naked X server creates slightly different event
+# sequences than running on a normal desktop
+# TEST_PROGS                   += crossingevents
+#crossingevents_SOURCES                 = crossingevents.c
+#crossingevents_LDADD           = $(progs_ldadd)
+
+TEST_PROGS                     += filechooser
+filechooser_SOURCES             = filechooser.c
+filechooser_LDADD               = $(progs_ldadd)
+
+TEST_PROGS                     += builder
+builder_SOURCES                         = builder.c
+builder_LDADD                   = $(progs_ldadd)
+builder_LDFLAGS                         = -export-dynamic
+
+TEST_PROGS                     += templates
+templates_SOURCES               = templates.c
+templates_LDADD                         = $(progs_ldadd)
+
+if OS_UNIX
+#TEST_PROGS                    += defaultvalue
+#defaultvalue_SOURCES           = defaultvalue.c
+#defaultvalue_LDADD             = $(progs_ldadd)
+endif
+
+TEST_PROGS                     += textbuffer
+textbuffer_SOURCES              = textbuffer.c
+textbuffer_LDADD                = $(progs_ldadd)
+
+TEST_PROGS                     += textiter
+textiter_SOURCES                = textiter.c
+textiter_LDADD                  = $(progs_ldadd)
+
+TEST_PROGS                     += expander
+expander_SOURCES                = expander.c
+expander_LDADD                  = $(progs_ldadd)
+
+TEST_PROGS                     += action
+action_SOURCES                  = action.c
+action_LDADD                    = $(progs_ldadd)
+
+TEST_PROGS                     += stylecontext
+stylecontext_SOURCES            = stylecontext.c
+stylecontext_LDADD              = $(progs_ldadd)
+
+TEST_PROGS                     += papersize
+papersize_SOURCES               = papersize.c
+papersize_LDADD                         = $(progs_ldadd)
+
+TEST_PROGS                     += cellarea
+cellarea_SOURCES                = cellarea.c
+cellarea_LDADD                  = $(progs_ldadd)
+
+TEST_PROGS                     += treepath
+treepath_SOURCES                = treepath.c
+treepath_LDADD                  = $(progs_ldadd)
+
+TEST_PROGS                     += accessible
+accessible_SOURCES              = accessible.c
+accessible_LDADD                = $(progs_ldadd)
+
+TEST_PROGS                     += entry
+entry_SOURCES                   = entry.c
+entry_LDADD                     = $(progs_ldadd)
+
+TEST_PROGS                     += grid
+grid_SOURCES                    = grid.c
+grid_LDADD                      = $(progs_ldadd)
+
+TEST_PROGS                     += rbtree
+rbtree_CFLAGS                   = -DGTK_COMPILATION -UG_ENABLE_DEBUG
+rbtree_SOURCES                  = rbtree.c \
+                                  $(top_srcdir)/gtk/gtkrbtree.h \
+                                  $(top_srcdir)/gtk/gtkrbtree.c
+rbtree_LDADD                    = $(GTK_DEP_LIBS)
+
+TEST_PROGS                     += bitmask
+bitmask_CFLAGS                  = -DGTK_COMPILATION -UG_ENABLE_DEBUG
+bitmask_SOURCES                         = bitmask.c \
+                                  $(top_srcdir)/gtk/gtkbitmaskprivate.h \
+                                  $(top_srcdir)/gtk/gtkallocatedbitmaskprivate.h \
+                                  $(top_srcdir)/gtk/gtkallocatedbitmask.c
+bitmask_LDADD                   = $(GTK_DEP_LIBS)
+
+TEST_PROGS                     += regression-tests
+regression_tests_SOURCES        = regression-tests.c
+regression_tests_LDADD          = $(progs_ldadd)
+
+TEST_PROGS                     += keyhash
+keyhash_SOURCES                         = keyhash.c \
+                                  $(top_srcdir)/gtk/gtkkeyhash.c \
+                                  $(top_srcdir)/gtk/gtkkeyhash.h \
+                                  $(top_srcdir)/gtk/gtkresources.c \
+                                  $(top_srcdir)/gtk/gtkresources.h \
+                                  $(top_srcdir)/gtk/gtkprivate.c \
+                                  $(top_srcdir)/gtk/gtkprivate.h
+keyhash_LDADD                   = $(progs_ldadd)
+keyhash_CFLAGS                  = -DGTK_COMPILATION \
+                                  -DGTK_LIBDIR=\"$(libdir)\" \
+                                  -DGTK_DATADIR=\"$(datadir)\" \
+                                  -DGTK_DATA_PREFIX=\"$(prefix)\" \
+                                  -DGTK_SYSCONFDIR=\"$(sysconfdir)\"
+
+TEST_PROGS                     += gtkmenu
+gtkmenu_SOURCES                         = gtkmenu.c
+gtkmenu_LDADD                   = $(progs_ldadd)
+
+
+TEST_PROGS                     += objects-finalize
+objects_finalize_SOURCES         = objects-finalize.c
+objects_finalize_LDADD          = $(progs_ldadd)
+
+TEST_PROGS                     += window
+window_SOURCES                  = window.c
+window_LDADD                    = $(progs_ldadd)
+
+EXTRA_DIST +=                          \
+       file-chooser-test-dir/empty     \
+       file-chooser-test-dir/text.txt
+
+-include $(top_srcdir)/git.mk
diff --git a/testsuite/gtk/accel.c b/testsuite/gtk/accel.c
new file mode 100644 (file)
index 0000000..d7ceb94
--- /dev/null
@@ -0,0 +1,123 @@
+/* accel.c - test accel parsing
+ * Copyright (C) 2011 Bastien Nocera <hadess@hadess.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <gtk/gtk.h>
+#include <locale.h>
+
+static void
+test_one_accel (const char *accel,
+               const char *exp_label,
+               gboolean has_keysym)
+{
+  guint accel_key;
+  GdkModifierType mods;
+  guint *keycodes;
+  char *label, *name;
+
+  accel_key = 0;
+  gtk_accelerator_parse_with_keycode (accel,
+                                     &accel_key,
+                                     &keycodes,
+                                     &mods);
+
+  if (has_keysym)
+    {
+      guint accel_key_2;
+      GdkModifierType mods_2;
+
+      gtk_accelerator_parse (accel,
+                             &accel_key_2,
+                             &mods_2);
+      g_assert (accel_key == accel_key_2);
+      g_assert (mods == mods_2);
+    }
+
+  if (has_keysym)
+    g_assert (accel_key != 0);
+  g_assert (keycodes);
+  g_assert (keycodes[0] != 0);
+
+  label = gtk_accelerator_get_label_with_keycode (NULL,
+                                                 accel_key,
+                                                 *keycodes,
+                                                 mods);
+
+  g_assert_cmpstr (label, ==, exp_label);
+
+  name = gtk_accelerator_name_with_keycode (NULL,
+                                           accel_key,
+                                           *keycodes,
+                                           mods);
+  g_assert_cmpstr (name, ==, accel);
+
+  g_free (keycodes);
+  g_free (label);
+  g_free (name);
+}
+
+static void
+accel1 (void)
+{
+  test_one_accel ("0xb3", "0xb3", FALSE);
+}
+
+static void
+accel2 (void)
+{
+  test_one_accel ("<Primary><Alt>z", "Ctrl+Alt+Z", TRUE);
+}
+
+static void
+accel3 (void)
+{
+  test_one_accel ("KP_7", "7", TRUE);
+}
+
+static void
+accel4 (void)
+{
+  test_one_accel ("<Primary>KP_7", "Ctrl+7", TRUE);
+}
+
+static void
+accel5 (void)
+{
+  test_one_accel ("<Shift>exclam", "Shift+!", TRUE);
+}
+
+static void
+keysyms (void)
+{
+  g_assert (gdk_keyval_from_name ("KP_7") == GDK_KEY_KP_7);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  setlocale (LC_ALL, "en_GB.UTF-8");
+
+  gtk_test_init (&argc, &argv);
+
+  g_test_add_func ("/keysyms", keysyms);
+
+  g_test_add_func ("/accel1", accel1);
+  g_test_add_func ("/accel2", accel2);
+  g_test_add_func ("/accel3", accel3);
+  g_test_add_func ("/accel4", accel4);
+  g_test_add_func ("/accel5", accel5);
+  return g_test_run();
+}
diff --git a/testsuite/gtk/accessible.c b/testsuite/gtk/accessible.c
new file mode 100644 (file)
index 0000000..03668c3
--- /dev/null
@@ -0,0 +1,35 @@
+#include <gtk/gtk.h>
+
+static void
+test_type (GType t)
+{
+  GtkWidget *w;
+  AtkObject *a;
+
+  if (g_type_is_a (t, GTK_TYPE_WIDGET))
+    {
+      w = (GtkWidget *)g_object_new (t, NULL);
+      a = gtk_widget_get_accessible (w);
+
+      g_assert (GTK_IS_ACCESSIBLE (a));
+      g_assert (gtk_accessible_get_widget (GTK_ACCESSIBLE (a)) == w);
+
+      g_object_unref (w);
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  const GType *tp;
+  guint i, n;
+
+  gtk_init (&argc, &argv);
+
+  tp = gtk_test_list_all_types (&n);
+
+  for (i = 0; i < n; n++)
+    test_type (tp[i]);
+
+  return 0;
+}
diff --git a/testsuite/gtk/action.c b/testsuite/gtk/action.c
new file mode 100644 (file)
index 0000000..df8c445
--- /dev/null
@@ -0,0 +1,90 @@
+/* GtkAction tests.
+ *
+ * Authors: Jan Arne Petersen <jpetersen@openismus.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+/* Fixture */
+
+typedef struct
+{
+  GtkAction *action;
+} ActionTest;
+
+static void
+action_test_setup (ActionTest    *fixture,
+                   gconstpointer  test_data)
+{
+  fixture->action = gtk_action_new ("name", "label", NULL, NULL);
+}
+
+static void
+action_test_teardown (ActionTest    *fixture,
+                      gconstpointer  test_data)
+{
+  g_object_unref (fixture->action);
+}
+
+static void
+notify_count_emmisions (GObject    *object,
+                       GParamSpec *pspec,
+                       gpointer    data)
+{
+  unsigned int *i = data;
+  (*i)++;
+}
+
+static void
+menu_item_label_notify_count (ActionTest    *fixture,
+                              gconstpointer  test_data)
+{
+  GtkWidget *item = gtk_menu_item_new ();
+  unsigned int emmisions = 0;
+
+  g_object_ref_sink (item);
+  g_signal_connect (item, "notify::label",
+                   G_CALLBACK (notify_count_emmisions), &emmisions);
+
+  gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item),
+                                        fixture->action);
+
+  g_assert_cmpuint (emmisions, ==, 1);
+
+  gtk_action_set_label (fixture->action, "new label");
+
+  g_assert_cmpuint (emmisions, ==, 2);
+
+  g_object_unref (item);
+}
+
+/* main */
+
+int
+main (int    argc,
+      char **argv)
+{
+  gtk_test_init (&argc, &argv, NULL);
+
+  g_test_add ("/Action/MenuItem/label-notify-count",
+              ActionTest, NULL,
+              action_test_setup,
+              menu_item_label_notify_count,
+              action_test_teardown);
+
+  return g_test_run ();
+}
+
diff --git a/testsuite/gtk/bitmask.c b/testsuite/gtk/bitmask.c
new file mode 100644 (file)
index 0000000..7d186a9
--- /dev/null
@@ -0,0 +1,385 @@
+/* GtkRBTree tests.
+ *
+ * Copyright (C) 2011, Red Hat, Inc.
+ * Authors: Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <locale.h>
+
+#include "../../gtk/gtkbitmaskprivate.h"
+
+#include <string.h>
+
+/* how often we run the random tests */
+#define N_RUNS 20
+
+/* how many tries we do in our random tests */
+#define N_TRIES 100
+
+/* the maximum index we use for bitmask values */
+#define MAX_INDEX 1000
+
+/* UTILITIES */
+
+static GtkBitmask *
+gtk_bitmask_new_parse (const char *string)
+{
+  guint i, length;
+  GtkBitmask *mask;
+
+  length = strlen (string);
+  mask = _gtk_bitmask_new ();
+
+  for (i = 0; i < length; i++)
+    {
+      if (string[i] == '0')
+        mask = _gtk_bitmask_set (mask, length - i - 1, FALSE);
+      else if (string[i] == '1')
+        mask = _gtk_bitmask_set (mask, length - i - 1, TRUE);
+      else
+        g_assert_not_reached ();
+    }
+
+  return mask;
+}
+
+#define assert_cmpmasks(mask,other) G_STMT_START { \
+  if (G_UNLIKELY (!_gtk_bitmask_equals (mask, other))) \
+    { \
+      char *mask_string = _gtk_bitmask_to_string (mask); \
+      char *other_string = _gtk_bitmask_to_string (other); \
+      char *msg = g_strdup_printf ("%s (%s) != %s (%s)", \
+                                   G_STRINGIFY (mask), mask_string, \
+                                   G_STRINGIFY (other), other_string); \
+      g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); \
+      g_free (msg); \
+      g_free (mask_string); \
+      g_free (other_string); \
+    } \
+}G_STMT_END
+
+static const char *tests[] = {
+                                                                                                                                   "0",
+                                                                                                                                   "1",
+                                                                                                     "1000000000000000000000000000000",
+                                                                                                    "10000000000000000000000000000000",
+                                                                     "100000000000000000000000000000000000000000000000000000000000000",
+                                                                    "1000000000000000000000000000000000000000000000000000000000000000",
+                                                                   "10000000000000000000000000000000000000000000000000000000000000000",
+  "1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010",
+  "1000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000",
+  "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
+};
+
+static GtkBitmask *masks[G_N_ELEMENTS (tests)];
+
+/* TEST */
+
+static void
+test_to_string (void)
+{
+  guint i;
+  char *to_string;
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    {
+      to_string = _gtk_bitmask_to_string (masks[i]);
+      g_assert_cmpstr (to_string, ==, tests[i]);
+      g_free (to_string);
+    }
+}
+
+static void
+test_is_empty (void)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    {
+      g_assert_cmpint (_gtk_bitmask_is_empty (masks[i]), ==, i == 0);
+    }
+}
+
+static void
+test_equals (void)
+{
+  guint i, j;
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    {
+      for (j = 0; j < G_N_ELEMENTS (tests); j++)
+        {
+          g_assert_cmpint (_gtk_bitmask_equals (masks[i], masks[j]), ==, i == j);
+        }
+    }
+}
+
+static void
+test_set (void)
+{
+  guint i, j;
+  guint indexes[N_TRIES];
+  GtkBitmask *copy;
+  const GtkBitmask *mask;
+
+  for (i = 0; i < N_RUNS; i++)
+    {
+      mask = masks[g_test_rand_int_range (0, G_N_ELEMENTS (tests))];
+      copy = _gtk_bitmask_copy (mask);
+
+      for (j = 0; j < N_TRIES; j++)
+        {
+          indexes[j] = g_test_rand_int_range (0, MAX_INDEX);
+          copy = _gtk_bitmask_set (copy, indexes[j], g_test_rand_bit ());
+        }
+
+      for (j = 0; j < N_TRIES; j++)
+        {
+          copy = _gtk_bitmask_set (copy, indexes[j], _gtk_bitmask_get (mask, indexes[j]));
+        }
+
+      assert_cmpmasks (copy, mask);
+      _gtk_bitmask_free (copy);
+    }
+}
+
+static void
+test_union (void)
+{
+  GtkBitmask *left, *right, *expected;
+  guint run, try, n_tries;
+
+  for (run = 0; run < N_RUNS; run++)
+    {
+      left = _gtk_bitmask_new ();
+      right = _gtk_bitmask_new ();
+      expected = _gtk_bitmask_new ();
+
+      n_tries = g_test_perf () ? N_TRIES : g_test_rand_int_range (0, N_TRIES);
+      for (try = 0; try < n_tries; try++)
+        {
+          guint id = g_test_rand_int_range (0, MAX_INDEX);
+
+          if (g_test_rand_bit ())
+            left = _gtk_bitmask_set (left, id, TRUE);
+          else
+            right = _gtk_bitmask_set (right, id, TRUE);
+
+          expected = _gtk_bitmask_set (expected, id, TRUE);
+        }
+
+      left = _gtk_bitmask_union (left, right);
+      right = _gtk_bitmask_union (right, left);
+
+      assert_cmpmasks (left, expected);
+      assert_cmpmasks (right, expected);
+      _gtk_bitmask_free (left);
+      _gtk_bitmask_free (right);
+      _gtk_bitmask_free (expected);
+    }
+}
+
+static void
+test_intersect (void)
+{
+  GtkBitmask *left, *right, *expected;
+  guint run, try;
+  gboolean intersects;
+
+  for (run = 0; run < N_RUNS; run++)
+    {
+      left = _gtk_bitmask_new ();
+      right = _gtk_bitmask_new ();
+      expected = _gtk_bitmask_new ();
+
+      for (try = 0; try < N_TRIES; try++)
+        {
+          guint id = g_test_rand_int_range (0, MAX_INDEX);
+          gboolean set = g_test_rand_bit ();
+
+          if (g_test_rand_bit ())
+            {
+              left = _gtk_bitmask_set (left, id, set);
+              expected = _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (right, id) : 0);
+            }
+          else
+            {
+              right = _gtk_bitmask_set (right, id, set);
+              expected = _gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (left, id) : 0);
+            }
+        }
+
+      intersects = _gtk_bitmask_intersects (left, right);
+      g_assert_cmpint (intersects, ==, _gtk_bitmask_intersects (right, left));
+      g_assert_cmpint (intersects, !=, _gtk_bitmask_is_empty (expected));
+
+      left = _gtk_bitmask_intersect (left, right);
+      right = _gtk_bitmask_intersect (right, left);
+
+      assert_cmpmasks (left, expected);
+      assert_cmpmasks (right, expected);
+      _gtk_bitmask_free (left);
+      _gtk_bitmask_free (right);
+      _gtk_bitmask_free (expected);
+    }
+}
+
+static void
+test_intersect_hardcoded (void)
+{
+  GtkBitmask *left, *right, *intersection, *expected;
+  const char *left_str, *right_str;
+  guint left_len, right_len;
+  guint i, l, r;
+
+  for (l = 0; l < G_N_ELEMENTS (tests); l++)
+    {
+      for (r = 0; r < G_N_ELEMENTS (tests); r++)
+        {
+          left = masks[l];
+          right = masks[r];
+          left_str = tests[l];
+          right_str = tests[r];
+          left_len = strlen (tests[l]);
+          right_len = strlen (tests[r]);
+
+          expected = _gtk_bitmask_new ();
+          if (left_len > right_len)
+            left_str += left_len - right_len;
+          if (right_len > left_len)
+            right_str += right_len - left_len;
+          i = MIN (right_len, left_len);
+          while (i--)
+            {
+              expected = _gtk_bitmask_set (expected, i, left_str[0] == '1' && right_str[0] == '1');
+              right_str++;
+              left_str++;
+            }
+
+          intersection = _gtk_bitmask_intersect (_gtk_bitmask_copy (left), right);
+
+          assert_cmpmasks (intersection, expected);
+          g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, !_gtk_bitmask_intersects (left, right));
+
+          _gtk_bitmask_free (intersection);
+          _gtk_bitmask_free (expected);
+        }
+    }
+}
+
+#define SWAP(_a, _b) G_STMT_START{ \
+  guint _tmp = _a; \
+  _a = _b; \
+  _b = _tmp; \
+}G_STMT_END
+
+static void
+test_invert_range (void)
+{
+  GtkBitmask *left, *right, *intersection, *expected;
+  guint run;
+  guint left_start, left_end, right_start, right_end, start, end;
+
+  for (run = 0; run < N_RUNS; run++)
+    {
+      left = _gtk_bitmask_new ();
+      right = _gtk_bitmask_new ();
+      expected = _gtk_bitmask_new ();
+
+      left_start = g_test_rand_int_range (0, MAX_INDEX);
+      left_end = g_test_rand_int_range (0, MAX_INDEX);
+      if (left_start > left_end)
+        SWAP (left_start, left_end);
+      right_start = g_test_rand_int_range (0, MAX_INDEX);
+      right_end = g_test_rand_int_range (0, MAX_INDEX);
+      if (right_start > right_end)
+        SWAP (right_start, right_end);
+      start = MAX (left_start, right_start);
+      end = MIN (left_end, right_end);
+
+      if (left_start != left_end)
+        left = _gtk_bitmask_invert_range (left, left_start, left_end);
+      if (right_start != right_end)
+        right = _gtk_bitmask_invert_range (right, right_start, right_end);
+      if (start < end)
+        expected = _gtk_bitmask_invert_range (expected, start, end);
+
+      intersection = _gtk_bitmask_copy (left);
+      intersection = _gtk_bitmask_intersect (intersection, right);
+
+      assert_cmpmasks (intersection, expected);
+
+      if (start < end)
+        expected = _gtk_bitmask_invert_range (expected, start, end);
+
+      g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, TRUE);
+
+      _gtk_bitmask_free (left);
+      _gtk_bitmask_free (right);
+      _gtk_bitmask_free (intersection);
+      _gtk_bitmask_free (expected);
+    }
+}
+
+/* SETUP & RUNNING */
+
+static void
+create_masks (void)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    masks[i] = gtk_bitmask_new_parse (tests[i]);
+}
+
+static void
+free_masks (void)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    {
+      _gtk_bitmask_free (masks[i]);
+      masks[i] = NULL;
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  int result;
+
+  g_test_init (&argc, &argv, NULL);
+  setlocale (LC_ALL, "C");
+  g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
+
+  create_masks ();
+
+  g_test_add_func ("/bitmask/to_string", test_to_string);
+  g_test_add_func ("/bitmask/is_empty", test_is_empty);
+  g_test_add_func ("/bitmask/equals", test_equals);
+  g_test_add_func ("/bitmask/set", test_set);
+  g_test_add_func ("/bitmask/union", test_union);
+  g_test_add_func ("/bitmask/intersect", test_intersect);
+  g_test_add_func ("/bitmask/intersect_hardcoded", test_intersect_hardcoded);
+  g_test_add_func ("/bitmask/invert_range", test_invert_range);
+
+  result = g_test_run ();
+
+  free_masks ();
+
+  return result;
+}
diff --git a/testsuite/gtk/builder.c b/testsuite/gtk/builder.c
new file mode 100644 (file)
index 0000000..e924a9a
--- /dev/null
@@ -0,0 +1,2776 @@
+/* buildertest.c
+ * Copyright (C) 2006-2007 Async Open Source
+ * Authors: Johan Dahlin
+ *          Henrique Romano
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <libintl.h>
+#include <locale.h>
+#include <math.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+/* exported for GtkBuilder */
+void signal_normal (GtkWindow *window, GParamSpec spec);
+void signal_after (GtkWindow *window, GParamSpec spec);
+void signal_object (GtkButton *button, GParamSpec spec);
+void signal_object_after (GtkButton *button, GParamSpec spec);
+void signal_first (GtkButton *button, GParamSpec spec);
+void signal_second (GtkButton *button, GParamSpec spec);
+void signal_extra (GtkButton *button, GParamSpec spec);
+void signal_extra2 (GtkButton *button, GParamSpec spec);
+
+/* Copied from gtkiconfactory.c; keep in sync! */
+struct _GtkIconSet
+{
+  guint ref_count;
+  GSList *sources;
+  GSList *cache;
+  guint cache_size;
+  guint cache_serial;
+};
+
+
+static GtkBuilder *
+builder_new_from_string (const gchar *buffer,
+                         gsize length,
+                         const gchar *domain)
+{
+  GtkBuilder *builder;
+  GError *error = NULL;
+
+  builder = gtk_builder_new ();
+  if (domain)
+    gtk_builder_set_translation_domain (builder, domain);
+  gtk_builder_add_from_string (builder, buffer, length, &error);
+  if (error)
+    {
+      g_print ("ERROR: %s", error->message);
+      g_error_free (error);
+    }
+
+  return builder;
+}
+
+static void
+test_parser (void)
+{
+  GtkBuilder *builder;
+  GError *error;
+  
+  builder = gtk_builder_new ();
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, "<xxx/>", -1, &error);
+  g_assert (g_error_matches (error, 
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_UNHANDLED_TAG));
+  g_error_free (error);
+  
+  error = NULL;
+  gtk_builder_add_from_string (builder, "<interface invalid=\"X\"/>", -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
+  g_error_free (error);
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, "<interface><child/></interface>", -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR, 
+                             GTK_BUILDER_ERROR_INVALID_TAG));
+  g_error_free (error);
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, "<interface><object class=\"GtkVBox\" id=\"a\"><object class=\"GtkHBox\" id=\"b\"/></object></interface>", -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_TAG));
+  g_error_free (error);
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, "<interface><object class=\"Unknown\" id=\"a\"></object></interface>", -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, "<interface><object class=\"GtkWidget\" id=\"a\" constructor=\"none\"></object></interface>", -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, "<interface><object class=\"GtkButton\" id=\"a\"><child internal-child=\"foobar\"><object class=\"GtkButton\" id=\"int\"/></child></object></interface>", -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, "<interface><object class=\"GtkButton\" id=\"a\"></object><object class=\"GtkButton\" id=\"a\"/></object></interface>", -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_DUPLICATE_ID));
+  g_error_free (error);
+
+  g_object_unref (builder);
+}
+
+static int normal = 0;
+static int after = 0;
+static int object = 0;
+static int object_after = 0;
+
+void /* exported for GtkBuilder */
+signal_normal (GtkWindow *window, GParamSpec spec)
+{
+  g_assert (GTK_IS_WINDOW (window));
+  g_assert (normal == 0);
+  g_assert (after == 0);
+
+  normal++;
+}
+
+void /* exported for GtkBuilder */
+signal_after (GtkWindow *window, GParamSpec spec)
+{
+  g_assert (GTK_IS_WINDOW (window));
+  g_assert (normal == 1);
+  g_assert (after == 0);
+  
+  after++;
+}
+
+void /* exported for GtkBuilder */
+signal_object (GtkButton *button, GParamSpec spec)
+{
+  g_assert (GTK_IS_BUTTON (button));
+  g_assert (object == 0);
+  g_assert (object_after == 0);
+
+  object++;
+}
+
+void /* exported for GtkBuilder */
+signal_object_after (GtkButton *button, GParamSpec spec)
+{
+  g_assert (GTK_IS_BUTTON (button));
+  g_assert (object == 1);
+  g_assert (object_after == 0);
+
+  object_after++;
+}
+
+void /* exported for GtkBuilder */
+signal_first (GtkButton *button, GParamSpec spec)
+{
+  g_assert (normal == 0);
+  normal = 10;
+}
+
+void /* exported for GtkBuilder */
+signal_second (GtkButton *button, GParamSpec spec)
+{
+  g_assert (normal == 10);
+  normal = 20;
+}
+
+void /* exported for GtkBuilder */
+signal_extra (GtkButton *button, GParamSpec spec)
+{
+  g_assert (normal == 20);
+  normal = 30;
+}
+
+void /* exported for GtkBuilder */
+signal_extra2 (GtkButton *button, GParamSpec spec)
+{
+  g_assert (normal == 30);
+  normal = 40;
+}
+
+static void
+test_connect_signals (void)
+{
+  GtkBuilder *builder;
+  GObject *window;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkButton\" id=\"button\"/>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <signal name=\"notify::title\" handler=\"signal_normal\"/>"
+    "    <signal name=\"notify::title\" handler=\"signal_after\" after=\"yes\"/>"
+    "    <signal name=\"notify::title\" handler=\"signal_object\""
+    "            object=\"button\"/>"
+    "    <signal name=\"notify::title\" handler=\"signal_object_after\""
+    "            object=\"button\" after=\"yes\"/>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer_order[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <signal name=\"notify::title\" handler=\"signal_first\"/>"
+    "    <signal name=\"notify::title\" handler=\"signal_second\"/>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer_extra[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window2\">"
+    "    <signal name=\"notify::title\" handler=\"signal_extra\"/>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer_extra2[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window3\">"
+    "    <signal name=\"notify::title\" handler=\"signal_extra2\"/>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer_after_child[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkButton\" id=\"button1\"/>"
+    "    </child>"
+    "    <signal name=\"notify::title\" handler=\"signal_normal\"/>"
+    "  </object>"
+    "</interface>";
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  gtk_builder_connect_signals (builder, NULL);
+
+  window = gtk_builder_get_object (builder, "window1");
+  gtk_window_set_title (GTK_WINDOW (window), "test");
+
+  g_assert_cmpint (normal, ==, 1);
+  g_assert_cmpint (after, ==, 1);
+  g_assert_cmpint (object, ==, 1);
+  g_assert_cmpint (object_after, ==, 1);
+
+  gtk_widget_destroy (GTK_WIDGET (window));
+  g_object_unref (builder);
+  
+  builder = builder_new_from_string (buffer_order, -1, NULL);
+  gtk_builder_connect_signals (builder, NULL);
+  window = gtk_builder_get_object (builder, "window1");
+  normal = 0;
+  gtk_window_set_title (GTK_WINDOW (window), "test");
+  g_assert (normal == 20);
+
+  gtk_widget_destroy (GTK_WIDGET (window));
+
+  gtk_builder_add_from_string (builder, buffer_extra,
+                              strlen (buffer_extra), NULL);
+  gtk_builder_add_from_string (builder, buffer_extra2,
+                              strlen (buffer_extra2), NULL);
+  gtk_builder_connect_signals (builder, NULL);
+  window = gtk_builder_get_object (builder, "window2");
+  gtk_window_set_title (GTK_WINDOW (window), "test");
+  g_assert (normal == 30);
+
+  gtk_widget_destroy (GTK_WIDGET (window));
+  window = gtk_builder_get_object (builder, "window3");
+  gtk_window_set_title (GTK_WINDOW (window), "test");
+  g_assert (normal == 40);
+  gtk_widget_destroy (GTK_WIDGET (window));
+  
+  g_object_unref (builder);
+
+  /* new test, reset globals */
+  after = 0;
+  normal = 0;
+  
+  builder = builder_new_from_string (buffer_after_child, -1, NULL);
+  window = gtk_builder_get_object (builder, "window1");
+  gtk_builder_connect_signals (builder, NULL);
+  gtk_window_set_title (GTK_WINDOW (window), "test");
+
+  g_assert (normal == 1);
+  gtk_widget_destroy (GTK_WIDGET (window));
+  g_object_unref (builder);
+}
+
+static void
+test_uimanager_simple (void)
+{
+  GtkBuilder *builder;
+  GObject *window, *uimgr, *menubar;
+  GObject *menu, *label;
+  GList *children;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkUIManager\" id=\"uimgr1\"/>"
+    "</interface>";
+    
+  const gchar buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkUIManager\" id=\"uimgr1\">"
+    "    <child>"
+    "      <object class=\"GtkActionGroup\" id=\"ag1\">"
+    "        <child>"
+    "          <object class=\"GtkAction\" id=\"file\">"
+    "            <property name=\"label\">_File</property>"
+    "          </object>"
+    "          <accelerator key=\"n\" modifiers=\"GDK_CONTROL_MASK\"/>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "    <ui>"
+    "      <menubar name=\"menubar1\">"
+    "        <menu action=\"file\">"
+    "        </menu>"
+    "      </menubar>"
+    "    </ui>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkMenuBar\" id=\"menubar1\" constructor=\"uimgr1\"/>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+
+  uimgr = gtk_builder_get_object (builder, "uimgr1");
+  g_assert (GTK_IS_UI_MANAGER (uimgr));
+  g_object_unref (builder);
+  
+  builder = builder_new_from_string (buffer2, -1, NULL);
+
+  menubar = gtk_builder_get_object (builder, "menubar1");
+  g_assert (GTK_IS_MENU_BAR (menubar));
+
+  children = gtk_container_get_children (GTK_CONTAINER (menubar));
+  menu = children->data;
+  g_assert (GTK_IS_MENU_ITEM (menu));
+  g_assert (strcmp (gtk_widget_get_name (GTK_WIDGET (menu)), "file") == 0);
+  g_list_free (children);
+  
+  label = G_OBJECT (gtk_bin_get_child (GTK_BIN (menu)));
+  g_assert (GTK_IS_LABEL (label));
+  g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
+
+  window = gtk_builder_get_object (builder, "window1");
+  gtk_widget_destroy (GTK_WIDGET (window));
+  g_object_unref (builder);
+}
+
+static void
+test_domain (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer1[] = "<interface/>";
+  const gchar buffer2[] = "<interface domain=\"domain\"/>";
+  const gchar *domain;
+  
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  domain = gtk_builder_get_translation_domain (builder);
+  g_assert (domain == NULL);
+  g_object_unref (builder);
+  
+  builder = builder_new_from_string (buffer1, -1, "domain-1");
+  domain = gtk_builder_get_translation_domain (builder);
+  g_assert (domain);
+  g_assert (strcmp (domain, "domain-1") == 0);
+  g_object_unref (builder);
+
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  domain = gtk_builder_get_translation_domain (builder);
+  g_assert (domain == NULL);
+  g_object_unref (builder);
+}
+
+#if 0
+static void
+test_translation (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkLabel\" id=\"label\">"
+    "        <property name=\"label\" translatable=\"yes\">File</property>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GtkLabel *window, *label;
+
+  setlocale (LC_ALL, "sv_SE");
+  textdomain ("builder");
+  bindtextdomain ("builder", "tests");
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  label = GTK_LABEL (gtk_builder_get_object (builder, "label"));
+  g_assert (strcmp (gtk_label_get_text (label), "Arkiv") == 0);
+
+  window = gtk_builder_get_object (builder, "window1");
+  gtk_widget_destroy (GTK_WIDGET (window));
+  g_object_unref (builder);
+}
+#endif
+
+static void
+test_sizegroup (void)
+{
+  GtkBuilder * builder;
+  const gchar buffer1[] =
+    "<interface domain=\"test\">"
+    "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
+    "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
+    "    <widgets>"
+    "      <widget name=\"radio1\"/>"
+    "      <widget name=\"radio2\"/>"
+    "    </widgets>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"vbox1\">"
+    "        <child>"
+    "          <object class=\"GtkRadioButton\" id=\"radio1\"/>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkRadioButton\" id=\"radio2\"/>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer2[] =
+    "<interface domain=\"test\">"
+    "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
+    "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
+    "    <widgets>"
+    "    </widgets>"
+    "   </object>"
+    "</interface>";
+  const gchar buffer3[] =
+    "<interface domain=\"test\">"
+    "  <object class=\"GtkSizeGroup\" id=\"sizegroup1\">"
+    "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
+    "    <widgets>"
+    "      <widget name=\"radio1\"/>"
+    "      <widget name=\"radio2\"/>"
+    "    </widgets>"
+    "  </object>"
+    "  <object class=\"GtkSizeGroup\" id=\"sizegroup2\">"
+    "    <property name=\"mode\">GTK_SIZE_GROUP_HORIZONTAL</property>"
+    "    <widgets>"
+    "      <widget name=\"radio1\"/>"
+    "      <widget name=\"radio2\"/>"
+    "    </widgets>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"vbox1\">"
+    "        <child>"
+    "          <object class=\"GtkRadioButton\" id=\"radio1\"/>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkRadioButton\" id=\"radio2\"/>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GObject *sizegroup;
+  GSList *widgets;
+
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  sizegroup = gtk_builder_get_object (builder, "sizegroup1");
+  widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
+  g_assert (g_slist_length (widgets) == 2);
+  g_slist_free (widgets);
+  g_object_unref (builder);
+
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  sizegroup = gtk_builder_get_object (builder, "sizegroup1");
+  widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
+  g_assert (g_slist_length (widgets) == 0);
+  g_slist_free (widgets);
+  g_object_unref (builder);
+
+  builder = builder_new_from_string (buffer3, -1, NULL);
+  sizegroup = gtk_builder_get_object (builder, "sizegroup1");
+  widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
+  g_assert (g_slist_length (widgets) == 2);
+  g_slist_free (widgets);
+  sizegroup = gtk_builder_get_object (builder, "sizegroup2");
+  widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
+  g_assert (g_slist_length (widgets) == 2);
+  g_slist_free (widgets);
+
+#if 0
+  {
+    GObject *window;
+    window = gtk_builder_get_object (builder, "window1");
+    gtk_widget_destroy (GTK_WIDGET (window));
+  }
+#endif  
+  g_object_unref (builder);
+}
+
+static void
+test_list_store (void)
+{
+  const gchar buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkListStore\" id=\"liststore1\">"
+    "    <columns>"
+    "      <column type=\"gchararray\"/>"
+    "      <column type=\"guint\"/>"
+    "    </columns>"
+    "  </object>"
+    "</interface>";
+  const char buffer2[] = 
+    "<interface>"
+    "  <object class=\"GtkListStore\" id=\"liststore1\">"
+    "    <columns>"
+    "      <column type=\"gchararray\"/>"
+    "      <column type=\"gchararray\"/>"
+    "      <column type=\"gint\"/>"
+    "    </columns>"
+    "    <data>"
+    "      <row>"
+    "        <col id=\"0\" translatable=\"yes\">John</col>"
+    "        <col id=\"1\" context=\"foo\">Doe</col>"
+    "        <col id=\"2\" comment=\"foobar\">25</col>"
+    "      </row>"
+    "      <row>"
+    "        <col id=\"0\">Johan</col>"
+    "        <col id=\"1\">Dole</col>"
+    "        <col id=\"2\">50</col>"
+    "      </row>"
+    "    </data>"
+    "  </object>"
+    "</interface>";
+  const char buffer3[] = 
+    "<interface>"
+    "  <object class=\"GtkListStore\" id=\"liststore1\">"
+    "    <columns>"
+    "      <column type=\"gchararray\"/>"
+    "      <column type=\"gchararray\"/>"
+    "      <column type=\"gint\"/>"
+    "    </columns>"
+    "    <data>"
+    "      <row>"
+    "        <col id=\"1\" context=\"foo\">Doe</col>"
+    "        <col id=\"0\" translatable=\"yes\">John</col>"
+    "        <col id=\"2\" comment=\"foobar\">25</col>"
+    "      </row>"
+    "      <row>"
+    "        <col id=\"2\">50</col>"
+    "        <col id=\"1\">Dole</col>"
+    "        <col id=\"0\">Johan</col>"
+    "      </row>"
+    "      <row>"
+    "        <col id=\"2\">19</col>"
+    "      </row>"
+    "    </data>"
+    "  </object>"
+    "</interface>";
+  GtkBuilder *builder;
+  GObject *store;
+  GtkTreeIter iter;
+  gchar *surname, *lastname;
+  int age;
+  
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  store = gtk_builder_get_object (builder, "liststore1");
+  g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 2);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_UINT);
+  g_object_unref (builder);
+  
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  store = gtk_builder_get_object (builder, "liststore1");
+  g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 3);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_STRING);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2) == G_TYPE_INT);
+  
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter) == TRUE);
+  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+                      0, &surname,
+                      1, &lastname,
+                      2, &age,
+                      -1);
+  g_assert (surname != NULL);
+  g_assert (strcmp (surname, "John") == 0);
+  g_free (surname);
+  g_assert (lastname != NULL);
+  g_assert (strcmp (lastname, "Doe") == 0);
+  g_free (lastname);
+  g_assert (age == 25);
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
+  
+  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+                      0, &surname,
+                      1, &lastname,
+                      2, &age,
+                      -1);
+  g_assert (surname != NULL);
+  g_assert (strcmp (surname, "Johan") == 0);
+  g_free (surname);
+  g_assert (lastname != NULL);
+  g_assert (strcmp (lastname, "Dole") == 0);
+  g_free (lastname);
+  g_assert (age == 50);
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == FALSE);
+
+  g_object_unref (builder);  
+
+  builder = builder_new_from_string (buffer3, -1, NULL);
+  store = gtk_builder_get_object (builder, "liststore1");
+  g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 3);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_STRING);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2) == G_TYPE_INT);
+  
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter) == TRUE);
+  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+                      0, &surname,
+                      1, &lastname,
+                      2, &age,
+                      -1);
+  g_assert (surname != NULL);
+  g_assert (strcmp (surname, "John") == 0);
+  g_free (surname);
+  g_assert (lastname != NULL);
+  g_assert (strcmp (lastname, "Doe") == 0);
+  g_free (lastname);
+  g_assert (age == 25);
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
+  
+  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+                      0, &surname,
+                      1, &lastname,
+                      2, &age,
+                      -1);
+  g_assert (surname != NULL);
+  g_assert (strcmp (surname, "Johan") == 0);
+  g_free (surname);
+  g_assert (lastname != NULL);
+  g_assert (strcmp (lastname, "Dole") == 0);
+  g_free (lastname);
+  g_assert (age == 50);
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == TRUE);
+  
+  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
+                      0, &surname,
+                      1, &lastname,
+                      2, &age,
+                      -1);
+  g_assert (surname == NULL);
+  g_assert (lastname == NULL);
+  g_assert (age == 19);
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter) == FALSE);
+
+  g_object_unref (builder);
+}
+
+static void
+test_tree_store (void)
+{
+  const gchar buffer[] =
+    "<interface domain=\"test\">"
+    "  <object class=\"GtkTreeStore\" id=\"treestore1\">"
+    "    <columns>"
+    "      <column type=\"gchararray\"/>"
+    "      <column type=\"guint\"/>"
+    "    </columns>"
+    "  </object>"
+    "</interface>";
+  GtkBuilder *builder;
+  GObject *store;
+  
+  builder = builder_new_from_string (buffer, -1, NULL);
+  store = gtk_builder_get_object (builder, "treestore1");
+  g_assert (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)) == 2);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0) == G_TYPE_STRING);
+  g_assert (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1) == G_TYPE_UINT);
+  
+  g_object_unref (builder);
+}
+
+static void
+test_types (void)
+{
+  const gchar buffer[] = 
+    "<interface>"
+    "  <object class=\"GtkAction\" id=\"action\"/>"
+    "  <object class=\"GtkActionGroup\" id=\"actiongroup\"/>"
+    "  <object class=\"GtkAlignment\" id=\"alignment\"/>"
+    "  <object class=\"GtkArrow\" id=\"arrow\"/>"
+    "  <object class=\"GtkButton\" id=\"button\"/>"
+    "  <object class=\"GtkCheckButton\" id=\"checkbutton\"/>"
+    "  <object class=\"GtkDialog\" id=\"dialog\"/>"
+    "  <object class=\"GtkDrawingArea\" id=\"drawingarea\"/>"
+    "  <object class=\"GtkEventBox\" id=\"eventbox\"/>"
+    "  <object class=\"GtkEntry\" id=\"entry\"/>"
+    "  <object class=\"GtkFontButton\" id=\"fontbutton\"/>"
+    "  <object class=\"GtkHButtonBox\" id=\"hbuttonbox\"/>"
+    "  <object class=\"GtkHBox\" id=\"hbox\"/>"
+    "  <object class=\"GtkHPaned\" id=\"hpaned\"/>"
+    "  <object class=\"GtkHScale\" id=\"hscale\"/>"
+    "  <object class=\"GtkHScrollbar\" id=\"hscrollbar\"/>"
+    "  <object class=\"GtkHSeparator\" id=\"hseparator\"/>"
+    "  <object class=\"GtkImage\" id=\"image\"/>"
+    "  <object class=\"GtkLabel\" id=\"label\"/>"
+    "  <object class=\"GtkListStore\" id=\"liststore\"/>"
+    "  <object class=\"GtkMenuBar\" id=\"menubar\"/>"
+    "  <object class=\"GtkNotebook\" id=\"notebook\"/>"
+    "  <object class=\"GtkProgressBar\" id=\"progressbar\"/>"
+    "  <object class=\"GtkRadioButton\" id=\"radiobutton\"/>"
+    "  <object class=\"GtkSizeGroup\" id=\"sizegroup\"/>"
+    "  <object class=\"GtkScrolledWindow\" id=\"scrolledwindow\"/>"
+    "  <object class=\"GtkSpinButton\" id=\"spinbutton\"/>"
+    "  <object class=\"GtkStatusbar\" id=\"statusbar\"/>"
+    "  <object class=\"GtkTextView\" id=\"textview\"/>"
+    "  <object class=\"GtkToggleAction\" id=\"toggleaction\"/>"
+    "  <object class=\"GtkToggleButton\" id=\"togglebutton\"/>"
+    "  <object class=\"GtkToolbar\" id=\"toolbar\"/>"
+    "  <object class=\"GtkTreeStore\" id=\"treestore\"/>"
+    "  <object class=\"GtkTreeView\" id=\"treeview\"/>"
+    "  <object class=\"GtkTable\" id=\"table\"/>"
+    "  <object class=\"GtkVBox\" id=\"vbox\"/>"
+    "  <object class=\"GtkVButtonBox\" id=\"vbuttonbox\"/>"
+    "  <object class=\"GtkVScrollbar\" id=\"vscrollbar\"/>"
+    "  <object class=\"GtkVSeparator\" id=\"vseparator\"/>"
+    "  <object class=\"GtkViewport\" id=\"viewport\"/>"
+    "  <object class=\"GtkVPaned\" id=\"vpaned\"/>"
+    "  <object class=\"GtkVScale\" id=\"vscale\"/>"
+    "  <object class=\"GtkWindow\" id=\"window\"/>"
+    "  <object class=\"GtkUIManager\" id=\"uimanager\"/>"
+    "</interface>";
+  const gchar buffer2[] = 
+    "<interface>"
+    "  <object type-func=\"gtk_window_get_type\" id=\"window\"/>"
+    "</interface>";
+  const gchar buffer3[] = 
+    "<interface>"
+    "  <object type-func=\"xxx_invalid_get_type_function\" id=\"window\"/>"
+    "</interface>";
+  GtkBuilder *builder;
+  GObject *window;
+  GError *error;
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "dialog")));
+  gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "window")));
+  g_object_unref (builder);
+
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  window = gtk_builder_get_object (builder, "window");
+  g_assert (GTK_IS_WINDOW (window));
+  gtk_widget_destroy (GTK_WIDGET (window));
+  g_object_unref (builder);
+  
+  error = NULL;
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_string (builder, buffer3, -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION));
+  g_error_free (error);
+  g_object_unref (builder);
+}
+
+static void
+test_spin_button (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "<object class=\"GtkAdjustment\" id=\"adjustment1\">"
+    "<property name=\"lower\">0</property>"
+    "<property name=\"upper\">10</property>"
+    "<property name=\"step-increment\">2</property>"
+    "<property name=\"page-increment\">3</property>"
+    "<property name=\"page-size\">0</property>"
+    "<property name=\"value\">1</property>"
+    "</object>"
+    "<object class=\"GtkSpinButton\" id=\"spinbutton1\">"
+    "<property name=\"visible\">True</property>"
+    "<property name=\"adjustment\">adjustment1</property>"
+    "</object>"
+    "</interface>";
+  GObject *obj;
+  GtkAdjustment *adjustment;
+  gdouble value;
+  
+  builder = builder_new_from_string (buffer, -1, NULL);
+  obj = gtk_builder_get_object (builder, "spinbutton1");
+  g_assert (GTK_IS_SPIN_BUTTON (obj));
+  adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (obj));
+  g_assert (GTK_IS_ADJUSTMENT (adjustment));
+  g_object_get (adjustment, "value", &value, NULL);
+  g_assert (value == 1);
+  g_object_get (adjustment, "lower", &value, NULL);
+  g_assert (value == 0);
+  g_object_get (adjustment, "upper", &value, NULL);
+  g_assert (value == 10);
+  g_object_get (adjustment, "step-increment", &value, NULL);
+  g_assert (value == 2);
+  g_object_get (adjustment, "page-increment", &value, NULL);
+  g_assert (value == 3);
+  g_object_get (adjustment, "page-size", &value, NULL);
+  g_assert (value == 0);
+  
+  g_object_unref (builder);
+}
+
+static void
+test_notebook (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkNotebook\" id=\"notebook1\">"
+    "    <child>"
+    "      <object class=\"GtkLabel\" id=\"label1\">"
+    "        <property name=\"label\">label1</property>"
+    "      </object>"
+    "    </child>"
+    "    <child type=\"tab\">"
+    "      <object class=\"GtkLabel\" id=\"tablabel1\">"
+    "        <property name=\"label\">tab_label1</property>"
+    "      </object>"
+    "    </child>"
+    "    <child>"
+    "      <object class=\"GtkLabel\" id=\"label2\">"
+    "        <property name=\"label\">label2</property>"
+    "      </object>"
+    "    </child>"
+    "    <child type=\"tab\">"
+    "      <object class=\"GtkLabel\" id=\"tablabel2\">"
+    "        <property name=\"label\">tab_label2</property>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GObject *notebook;
+  GtkWidget *label;
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  notebook = gtk_builder_get_object (builder, "notebook1");
+  g_assert (notebook != NULL);
+  g_assert (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) == 2);
+
+  label = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0);
+  g_assert (GTK_IS_LABEL (label));
+  g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "label1") == 0);
+  label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), label);
+  g_assert (GTK_IS_LABEL (label));
+  g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "tab_label1") == 0);
+
+  label = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1);
+  g_assert (GTK_IS_LABEL (label));
+  g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "label2") == 0);
+  label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), label);
+  g_assert (GTK_IS_LABEL (label));
+  g_assert (strcmp (gtk_label_get_label (GTK_LABEL (label)), "tab_label2") == 0);
+
+  g_object_unref (builder);
+}
+
+static void
+test_construct_only_property (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <property name=\"type\">GTK_WINDOW_POPUP</property>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkTextTagTable\" id=\"tagtable1\"/>"
+    "  <object class=\"GtkTextBuffer\" id=\"textbuffer1\">"
+    "    <property name=\"tag-table\">tagtable1</property>"
+    "  </object>"
+    "</interface>";
+  GObject *widget, *tagtable, *textbuffer;
+  GtkWindowType type;
+  
+  builder = builder_new_from_string (buffer, -1, NULL);
+  widget = gtk_builder_get_object (builder, "window1");
+  g_object_get (widget, "type", &type, NULL);
+  g_assert (type == GTK_WINDOW_POPUP);
+
+  gtk_widget_destroy (GTK_WIDGET (widget));
+  g_object_unref (builder);
+
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  textbuffer = gtk_builder_get_object (builder, "textbuffer1");
+  g_assert (textbuffer != NULL);
+  g_object_get (textbuffer, "tag-table", &tagtable, NULL);
+  g_assert (tagtable == gtk_builder_get_object (builder, "tagtable1"));
+  g_object_unref (tagtable);
+  g_object_unref (builder);
+}
+
+static void
+test_object_properties (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"vbox\">"
+    "        <property name=\"border-width\">10</property>"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"label1\">"
+    "            <property name=\"mnemonic-widget\">spinbutton1</property>"
+    "          </object>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkSpinButton\" id=\"spinbutton1\"/>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window2\"/>"
+    "</interface>";
+  GObject *label, *spinbutton, *window;
+  
+  builder = builder_new_from_string (buffer, -1, NULL);
+  label = gtk_builder_get_object (builder, "label1");
+  g_assert (label != NULL);
+  spinbutton = gtk_builder_get_object (builder, "spinbutton1");
+  g_assert (spinbutton != NULL);
+  g_assert (spinbutton == (GObject*)gtk_label_get_mnemonic_widget (GTK_LABEL (label)));
+
+  gtk_builder_add_from_string (builder, buffer2, -1, NULL);
+  window = gtk_builder_get_object (builder, "window2");
+  g_assert (window != NULL);
+  gtk_widget_destroy (GTK_WIDGET (window));
+
+  g_object_unref (builder);
+}
+
+static void
+test_children (void)
+{
+  GtkBuilder * builder;
+  GtkWidget *content_area, *dialog_action_area;
+  GList *children;
+  const gchar buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkButton\" id=\"button1\">"
+    "        <property name=\"label\">Hello</property>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkDialog\" id=\"dialog1\">"
+    "    <child internal-child=\"vbox\">"
+    "      <object class=\"GtkVBox\" id=\"dialog1-vbox\">"
+    "        <property name=\"border-width\">10</property>"
+    "          <child internal-child=\"action_area\">"
+    "            <object class=\"GtkHButtonBox\" id=\"dialog1-action_area\">"
+    "              <property name=\"border-width\">20</property>"
+    "            </object>"
+    "          </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+
+  GObject *window, *button;
+  GObject *dialog, *vbox, *action_area;
+  
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  window = gtk_builder_get_object (builder, "window1");
+  g_assert (window != NULL);
+  g_assert (GTK_IS_WINDOW (window));
+
+  button = gtk_builder_get_object (builder, "button1");
+  g_assert (button != NULL);
+  g_assert (GTK_IS_BUTTON (button));
+  g_assert (gtk_widget_get_parent (GTK_WIDGET(button)) != NULL);
+  g_assert (strcmp (gtk_buildable_get_name (GTK_BUILDABLE (gtk_widget_get_parent (GTK_WIDGET (button)))), "window1") == 0);
+
+  gtk_widget_destroy (GTK_WIDGET (window));
+  g_object_unref (builder);
+  
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  dialog = gtk_builder_get_object (builder, "dialog1");
+  g_assert (dialog != NULL);
+  g_assert (GTK_IS_DIALOG (dialog));
+  children = gtk_container_get_children (GTK_CONTAINER (dialog));
+  g_assert (g_list_length (children) == 1);
+  g_list_free (children);
+  
+  vbox = gtk_builder_get_object (builder, "dialog1-vbox");
+  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+  g_assert (vbox != NULL);
+  g_assert (GTK_IS_BOX (vbox));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (vbox)) == GTK_ORIENTATION_VERTICAL);
+  g_assert (strcmp (gtk_buildable_get_name (GTK_BUILDABLE (gtk_widget_get_parent (GTK_WIDGET (vbox)))), "dialog1") == 0);
+  g_assert (gtk_container_get_border_width (GTK_CONTAINER (vbox)) == 10);
+  g_assert (strcmp (gtk_buildable_get_name (GTK_BUILDABLE (content_area)), "dialog1-vbox") == 0);
+
+  action_area = gtk_builder_get_object (builder, "dialog1-action_area");
+  dialog_action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
+  g_assert (action_area != NULL);
+  g_assert (GTK_IS_BUTTON_BOX (action_area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (action_area)) == GTK_ORIENTATION_HORIZONTAL);
+  g_assert (gtk_widget_get_parent (GTK_WIDGET (action_area)) != NULL);
+  g_assert (gtk_container_get_border_width (GTK_CONTAINER (action_area)) == 20);
+  g_assert (dialog_action_area != NULL);
+  g_assert (gtk_buildable_get_name (GTK_BUILDABLE (action_area)) != NULL);
+  g_assert (strcmp (gtk_buildable_get_name (GTK_BUILDABLE (dialog_action_area)), "dialog1-action_area") == 0);
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+  g_object_unref (builder);
+}
+
+static void
+test_child_properties (void)
+{
+  GtkBuilder * builder;
+  const gchar buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkBox\" id=\"vbox1\">"
+    "    <child>"
+    "      <object class=\"GtkLabel\" id=\"label1\"/>"
+    "      <packing>"
+    "        <property name=\"pack-type\">start</property>"
+    "      </packing>"
+    "    </child>"
+    "    <child>"
+    "      <object class=\"GtkLabel\" id=\"label2\"/>"
+    "      <packing>"
+    "        <property name=\"pack-type\">end</property>"
+    "      </packing>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+
+  GObject *label, *vbox;
+  GtkPackType pack_type;
+  
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  vbox = gtk_builder_get_object (builder, "vbox1");
+  g_assert (GTK_IS_BOX (vbox));
+
+  label = gtk_builder_get_object (builder, "label1");
+  g_assert (GTK_IS_LABEL (label));
+  gtk_container_child_get (GTK_CONTAINER (vbox),
+                           GTK_WIDGET (label),
+                           "pack-type",
+                           &pack_type,
+                           NULL);
+  g_assert (pack_type == GTK_PACK_START);
+  
+  label = gtk_builder_get_object (builder, "label2");
+  g_assert (GTK_IS_LABEL (label));
+  gtk_container_child_get (GTK_CONTAINER (vbox),
+                           GTK_WIDGET (label),
+                           "pack-type",
+                           &pack_type,
+                           NULL);
+  g_assert (pack_type == GTK_PACK_END);
+
+  g_object_unref (builder);
+}
+
+static void
+test_treeview_column (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "<object class=\"GtkListStore\" id=\"liststore1\">"
+    "  <columns>"
+    "    <column type=\"gchararray\"/>"
+    "    <column type=\"guint\"/>"
+    "  </columns>"
+    "  <data>"
+    "    <row>"
+    "      <col id=\"0\">John</col>"
+    "      <col id=\"1\">25</col>"
+    "    </row>"
+    "  </data>"
+    "</object>"
+    "<object class=\"GtkWindow\" id=\"window1\">"
+    "  <child>"
+    "    <object class=\"GtkTreeView\" id=\"treeview1\">"
+    "      <property name=\"visible\">True</property>"
+    "      <property name=\"model\">liststore1</property>"
+    "      <child>"
+    "        <object class=\"GtkTreeViewColumn\" id=\"column1\">"
+    "          <property name=\"title\">Test</property>"
+    "          <child>"
+    "            <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
+    "            <attributes>"
+    "              <attribute name=\"text\">1</attribute>"
+    "            </attributes>"
+    "          </child>"
+    "        </object>"
+    "      </child>"
+    "      <child>"
+    "        <object class=\"GtkTreeViewColumn\" id=\"column2\">"
+    "          <property name=\"title\">Number</property>"
+    "          <child>"
+    "            <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
+    "            <attributes>"
+    "              <attribute name=\"text\">0</attribute>"
+    "            </attributes>"
+    "          </child>"
+    "        </object>"
+    "      </child>"
+    "    </object>"
+    "  </child>"
+    "</object>"
+    "</interface>";
+  GObject *window, *treeview;
+  GtkTreeViewColumn *column;
+  GList *renderers;
+  GObject *renderer;
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  treeview = gtk_builder_get_object (builder, "treeview1");
+  g_assert (treeview);
+  g_assert (GTK_IS_TREE_VIEW (treeview));
+  column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 0);
+  g_assert (GTK_IS_TREE_VIEW_COLUMN (column));
+  g_assert (strcmp (gtk_tree_view_column_get_title (column), "Test") == 0);
+
+  renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
+  g_assert (g_list_length (renderers) == 1);
+  renderer = g_list_nth_data (renderers, 0);
+  g_assert (renderer);
+  g_assert (GTK_IS_CELL_RENDERER_TEXT (renderer));
+  g_list_free (renderers);
+
+  window = gtk_builder_get_object (builder, "window1");
+  gtk_widget_destroy (GTK_WIDGET (window));
+
+  g_object_unref (builder);
+}
+
+static void
+test_icon_view (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkListStore\" id=\"liststore1\">"
+    "    <columns>"
+    "      <column type=\"gchararray\"/>"
+    "      <column type=\"GdkPixbuf\"/>"
+    "    </columns>"
+    "    <data>"
+    "      <row>"
+    "        <col id=\"0\">test</col>"
+    "      </row>"
+    "    </data>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkIconView\" id=\"iconview1\">"
+    "        <property name=\"model\">liststore1</property>"
+    "        <property name=\"text-column\">0</property>"
+    "        <property name=\"pixbuf-column\">1</property>"
+    "        <property name=\"visible\">True</property>"
+    "        <child>"
+    "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
+    "          <attributes>"
+    "            <attribute name=\"text\">0</attribute>"
+    "          </attributes>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GObject *window, *iconview;
+  
+  builder = builder_new_from_string (buffer, -1, NULL);
+  iconview = gtk_builder_get_object (builder, "iconview1");
+  g_assert (iconview);
+  g_assert (GTK_IS_ICON_VIEW (iconview));
+
+  window = gtk_builder_get_object (builder, "window1");
+  gtk_widget_destroy (GTK_WIDGET (window));
+  g_object_unref (builder);
+}
+
+static void
+test_combo_box (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkListStore\" id=\"liststore1\">"
+    "    <columns>"
+    "      <column type=\"guint\"/>"
+    "      <column type=\"gchararray\"/>"
+    "    </columns>"
+    "    <data>"
+    "      <row>"
+    "        <col id=\"0\">1</col>"
+    "        <col id=\"1\">Foo</col>"
+    "      </row>"
+    "      <row>"
+    "        <col id=\"0\">2</col>"
+    "        <col id=\"1\">Bar</col>"
+    "      </row>"
+    "    </data>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkComboBox\" id=\"combobox1\">"
+    "        <property name=\"model\">liststore1</property>"
+    "        <property name=\"visible\">True</property>"
+    "        <child>"
+    "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
+    "          <attributes>"
+    "            <attribute name=\"text\">0</attribute>"
+    "          </attributes>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
+    "          <attributes>"
+    "            <attribute name=\"text\">1</attribute>"
+    "          </attributes>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GObject *window, *combobox;
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  combobox = gtk_builder_get_object (builder, "combobox1");
+  g_assert (combobox);
+
+  window = gtk_builder_get_object (builder, "window1");
+  gtk_widget_destroy (GTK_WIDGET (window));
+
+  g_object_unref (builder);
+}
+
+#if 0
+static void
+test_combo_box_entry (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkListStore\" id=\"liststore1\">"
+    "    <columns>"
+    "      <column type=\"guint\"/>"
+    "      <column type=\"gchararray\"/>"
+    "    </columns>"
+    "    <data>"
+    "      <row>"
+    "        <col id=\"0\">1</col>"
+    "        <col id=\"1\">Foo</col>"
+    "      </row>"
+    "      <row>"
+    "        <col id=\"0\">2</col>"
+    "        <col id=\"1\">Bar</col>"
+    "      </row>"
+    "    </data>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkComboBox\" id=\"comboboxentry1\">"
+    "        <property name=\"model\">liststore1</property>"
+    "        <property name=\"has-entry\">True</property>"
+    "        <property name=\"visible\">True</property>"
+    "        <child>"
+    "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
+    "            <attributes>"
+    "              <attribute name=\"text\">0</attribute>"
+    "            </attributes>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkCellRendererText\" id=\"renderer2\"/>"
+    "            <attributes>"
+    "              <attribute name=\"text\">1</attribute>"
+    "            </attributes>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GObject *window, *combobox, *renderer;
+  gchar *text;
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  combobox = gtk_builder_get_object (builder, "comboboxentry1");
+  g_assert (combobox);
+
+  renderer = gtk_builder_get_object (builder, "renderer2");
+  g_assert (renderer);
+  g_object_get (renderer, "text", &text, NULL);
+  g_assert (text);
+  g_assert (strcmp (text, "Bar") == 0);
+  g_free (text);
+
+  renderer = gtk_builder_get_object (builder, "renderer1");
+  g_assert (renderer);
+  g_object_get (renderer, "text", &text, NULL);
+  g_assert (text);
+  g_assert (strcmp (text, "2") == 0);
+  g_free (text);
+
+  window = gtk_builder_get_object (builder, "window1");
+  gtk_widget_destroy (GTK_WIDGET (window));
+
+  g_object_unref (builder);
+}
+#endif
+
+static void
+test_cell_view (void)
+{
+  GtkBuilder *builder;
+  const gchar *buffer =
+    "<interface>"
+    "  <object class=\"GtkListStore\" id=\"liststore1\">"
+    "    <columns>"
+    "      <column type=\"gchararray\"/>"
+    "    </columns>"
+    "    <data>"
+    "      <row>"
+    "        <col id=\"0\">test</col>"
+    "      </row>"
+    "    </data>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkCellView\" id=\"cellview1\">"
+    "        <property name=\"visible\">True</property>"
+    "        <property name=\"model\">liststore1</property>"
+    "        <accelerator key=\"f\" modifiers=\"GDK_CONTROL_MASK\" signal=\"grab_focus\"/>"
+    "        <child>"
+    "          <object class=\"GtkCellRendererText\" id=\"renderer1\"/>"
+    "          <attributes>"
+    "            <attribute name=\"text\">0</attribute>"
+    "          </attributes>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GObject *cellview;
+  GObject *model, *window;
+  GtkTreePath *path;
+  GList *renderers;
+  
+  builder = builder_new_from_string (buffer, -1, NULL);
+  cellview = gtk_builder_get_object (builder, "cellview1");
+  g_assert (builder);
+  g_assert (cellview);
+  g_assert (GTK_IS_CELL_VIEW (cellview));
+  g_object_get (cellview, "model", &model, NULL);
+  g_assert (model);
+  g_assert (GTK_IS_TREE_MODEL (model));
+  g_object_unref (model);
+  path = gtk_tree_path_new_first ();
+  gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (cellview), path);
+  
+  renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cellview));
+  g_assert (renderers);
+  g_assert (g_list_length (renderers) == 1);
+
+  window = gtk_builder_get_object (builder, "window1");
+  g_assert (window);
+  gtk_widget_destroy (GTK_WIDGET (window));
+  
+  g_object_unref (builder);
+}
+
+static void
+test_dialog (void)
+{
+  GtkBuilder * builder;
+  const gchar buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkDialog\" id=\"dialog1\">"
+    "    <child internal-child=\"vbox\">"
+    "      <object class=\"GtkVBox\" id=\"dialog1-vbox\">"
+    "          <child internal-child=\"action_area\">"
+    "            <object class=\"GtkHButtonBox\" id=\"dialog1-action_area\">"
+    "              <child>"
+    "                <object class=\"GtkButton\" id=\"button_cancel\"/>"
+    "              </child>"
+    "              <child>"
+    "                <object class=\"GtkButton\" id=\"button_ok\"/>"
+    "              </child>"
+    "            </object>"
+    "          </child>"
+    "      </object>"
+    "    </child>"
+    "    <action-widgets>"
+    "      <action-widget response=\"3\">button_ok</action-widget>"
+    "      <action-widget response=\"-5\">button_cancel</action-widget>"
+    "    </action-widgets>"
+    "  </object>"
+    "</interface>";
+
+  GObject *dialog1;
+  GObject *button_ok;
+  GObject *button_cancel;
+  
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  dialog1 = gtk_builder_get_object (builder, "dialog1");
+  button_ok = gtk_builder_get_object (builder, "button_ok");
+  g_assert (gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog1), GTK_WIDGET (button_ok)) == 3);
+  button_cancel = gtk_builder_get_object (builder, "button_cancel");
+  g_assert (gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog1), GTK_WIDGET (button_cancel)) == -5);
+  
+  gtk_widget_destroy (GTK_WIDGET (dialog1));
+  g_object_unref (builder);
+}
+
+static void
+test_message_dialog (void)
+{
+  GtkBuilder * builder;
+  const gchar buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkMessageDialog\" id=\"dialog1\">"
+    "    <child internal-child=\"message_area\">"
+    "      <object class=\"GtkVBox\" id=\"dialog-message-area\">"
+    "        <child>"
+    "          <object class=\"GtkExpander\" id=\"expander\"/>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+
+  GObject *dialog1;
+  GObject *expander;
+
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  dialog1 = gtk_builder_get_object (builder, "dialog1");
+  expander = gtk_builder_get_object (builder, "expander");
+  g_assert (GTK_IS_EXPANDER (expander));
+  g_assert (gtk_widget_get_parent (GTK_WIDGET (expander)) == gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog1)));
+
+  gtk_widget_destroy (GTK_WIDGET (dialog1));
+  g_object_unref (builder);
+}
+
+static void
+test_accelerators (void)
+{
+  GtkBuilder *builder;
+  const gchar *buffer =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkButton\" id=\"button1\">"
+    "        <accelerator key=\"q\" modifiers=\"GDK_CONTROL_MASK\" signal=\"clicked\"/>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  const gchar *buffer2 =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkTreeView\" id=\"treeview1\">"
+    "        <signal name=\"cursor-changed\" handler=\"gtk_main_quit\"/>"
+    "        <accelerator key=\"f\" modifiers=\"GDK_CONTROL_MASK\" signal=\"grab_focus\"/>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GObject *window1;
+  GSList *accel_groups;
+  GObject *accel_group;
+  
+  builder = builder_new_from_string (buffer, -1, NULL);
+  window1 = gtk_builder_get_object (builder, "window1");
+  g_assert (window1);
+  g_assert (GTK_IS_WINDOW (window1));
+
+  accel_groups = gtk_accel_groups_from_object (window1);
+  g_assert (g_slist_length (accel_groups) == 1);
+  accel_group = g_slist_nth_data (accel_groups, 0);
+  g_assert (accel_group);
+
+  gtk_widget_destroy (GTK_WIDGET (window1));
+  g_object_unref (builder);
+
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  window1 = gtk_builder_get_object (builder, "window1");
+  g_assert (window1);
+  g_assert (GTK_IS_WINDOW (window1));
+
+  accel_groups = gtk_accel_groups_from_object (window1);
+  g_assert (g_slist_length (accel_groups) == 1);
+  accel_group = g_slist_nth_data (accel_groups, 0);
+  g_assert (accel_group);
+
+  gtk_widget_destroy (GTK_WIDGET (window1));
+  g_object_unref (builder);
+}
+
+static void
+test_widget (void)
+{
+  const gchar *buffer =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkButton\" id=\"button1\">"
+    "         <property name=\"can-focus\">True</property>"
+    "         <property name=\"has-focus\">True</property>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+   "</interface>";
+  const gchar *buffer2 =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkButton\" id=\"button1\">"
+    "         <property name=\"can-default\">True</property>"
+    "         <property name=\"has-default\">True</property>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+   "</interface>";
+  const gchar *buffer3 =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"vbox1\">"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"label1\">"
+    "            <child internal-child=\"accessible\">"
+    "              <object class=\"AtkObject\" id=\"a11y-label1\">"
+    "                <property name=\"AtkObject::accessible-name\">A Label</property>"
+    "              </object>"
+    "            </child>"
+    "            <accessibility>"
+    "              <relation target=\"button1\" type=\"label-for\"/>"
+    "            </accessibility>"
+    "          </object>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkButton\" id=\"button1\">"
+    "            <accessibility>"
+    "              <action action_name=\"click\" description=\"Sliff\"/>"
+    "              <action action_name=\"clack\" translatable=\"yes\">Sniff</action>"
+    "            </accessibility>"
+    "          </object>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GtkBuilder *builder;
+  GObject *window1, *button1, *label1;
+  AtkObject *accessible;
+  AtkRelationSet *relation_set;
+  AtkRelation *relation;
+  char *name;
+  
+  builder = builder_new_from_string (buffer, -1, NULL);
+  button1 = gtk_builder_get_object (builder, "button1");
+
+#if 0
+  g_assert (gtk_widget_has_focus (GTK_WIDGET (button1)));
+#endif
+  window1 = gtk_builder_get_object (builder, "window1");
+  gtk_widget_destroy (GTK_WIDGET (window1));
+  
+  g_object_unref (builder);
+  
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  button1 = gtk_builder_get_object (builder, "button1");
+
+  g_assert (gtk_widget_get_receives_default (GTK_WIDGET (button1)));
+  
+  g_object_unref (builder);
+  
+  builder = builder_new_from_string (buffer3, -1, NULL);
+
+  window1 = gtk_builder_get_object (builder, "window1");
+  label1 = gtk_builder_get_object (builder, "label1");
+
+  accessible = gtk_widget_get_accessible (GTK_WIDGET (label1));
+  relation_set = atk_object_ref_relation_set (accessible);
+  g_return_if_fail (atk_relation_set_get_n_relations (relation_set) == 1);
+  relation = atk_relation_set_get_relation (relation_set, 0);
+  g_return_if_fail (relation != NULL);
+  g_return_if_fail (ATK_IS_RELATION (relation));
+  g_return_if_fail (atk_relation_get_relation_type (relation) != ATK_RELATION_LABELLED_BY);
+  g_object_unref (relation_set);
+
+  g_object_get (G_OBJECT (accessible), "accessible-name", &name, NULL);
+  g_return_if_fail (strcmp (name, "A Label") == 0);
+  g_free (name);
+  
+  gtk_widget_destroy (GTK_WIDGET (window1));
+  g_object_unref (builder);
+}
+
+static void
+test_window (void)
+{
+  const gchar *buffer1 =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "     <property name=\"title\"></property>"
+    "  </object>"
+   "</interface>";
+  const gchar *buffer2 =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "  </object>"
+   "</interface>";
+  GtkBuilder *builder;
+  GObject *window1;
+  gchar *title;
+  
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  window1 = gtk_builder_get_object (builder, "window1");
+  g_object_get (window1, "title", &title, NULL);
+  g_assert (strcmp (title, "") == 0);
+  g_free (title);
+  gtk_widget_destroy (GTK_WIDGET (window1));
+  g_object_unref (builder);
+
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  window1 = gtk_builder_get_object (builder, "window1");
+  gtk_widget_destroy (GTK_WIDGET (window1));
+  g_object_unref (builder);
+}
+
+static void
+test_value_from_string (void)
+{
+  GValue value = G_VALUE_INIT;
+  GError *error = NULL;
+  GtkBuilder *builder;
+
+  builder = gtk_builder_new ();
+  
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_STRING, "test", &value, &error));
+  g_assert (G_VALUE_HOLDS_STRING (&value));
+  g_assert (strcmp (g_value_get_string (&value), "test") == 0);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "true", &value, &error));
+  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
+  g_assert (g_value_get_boolean (&value) == TRUE);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "false", &value, &error));
+  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
+  g_assert (g_value_get_boolean (&value) == FALSE);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yes", &value, &error));
+  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
+  g_assert (g_value_get_boolean (&value) == TRUE);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "no", &value, &error));
+  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
+  g_assert (g_value_get_boolean (&value) == FALSE);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "0", &value, &error));
+  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
+  g_assert (g_value_get_boolean (&value) == FALSE);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "1", &value, &error));
+  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
+  g_assert (g_value_get_boolean (&value) == TRUE);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "tRuE", &value, &error));
+  g_assert (G_VALUE_HOLDS_BOOLEAN (&value));
+  g_assert (g_value_get_boolean (&value) == TRUE);
+  g_value_unset (&value);
+  
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "blaurgh", &value, &error) == FALSE);
+  g_value_unset (&value);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+  error = NULL;
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yess", &value, &error) == FALSE);
+  g_value_unset (&value);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+  error = NULL;
+  
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "trueee", &value, &error) == FALSE);
+  g_value_unset (&value);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+  error = NULL;
+  
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "", &value, &error) == FALSE);
+  g_value_unset (&value);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+  error = NULL;
+  
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "12345", &value, &error));
+  g_assert (G_VALUE_HOLDS_INT (&value));
+  g_assert (g_value_get_int (&value) == 12345);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_LONG, "9912345", &value, &error));
+  g_assert (G_VALUE_HOLDS_LONG (&value));
+  g_assert (g_value_get_long (&value) == 9912345);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_UINT, "2345", &value, &error));
+  g_assert (G_VALUE_HOLDS_UINT (&value));
+  g_assert (g_value_get_uint (&value) == 2345);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_FLOAT, "1.454", &value, &error));
+  g_assert (G_VALUE_HOLDS_FLOAT (&value));
+  g_assert (fabs (g_value_get_float (&value) - 1.454) < 0.00001);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_FLOAT, "abc", &value, &error) == FALSE);
+  g_value_unset (&value);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+  error = NULL;
+
+  g_assert (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "/-+,abc", &value, &error) == FALSE);
+  g_value_unset (&value);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+  error = NULL;
+
+  g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "toplevel", &value, &error) == TRUE);
+  g_assert (G_VALUE_HOLDS_ENUM (&value));
+  g_assert (g_value_get_enum (&value) == GTK_WINDOW_TOPLEVEL);
+  g_value_unset (&value);
+
+  g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "sliff", &value, &error) == FALSE);
+  g_value_unset (&value);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+  error = NULL;
+
+  g_assert (gtk_builder_value_from_string_type (builder, GTK_TYPE_WINDOW_TYPE, "foobar", &value, &error) == FALSE);
+  g_value_unset (&value);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_VALUE));
+  g_error_free (error);
+  error = NULL;
+  
+  g_object_unref (builder);
+}
+
+static gboolean model_freed = FALSE;
+
+static void
+model_weakref (gpointer data,
+               GObject *model)
+{
+  model_freed = TRUE;
+}
+
+static void
+test_reference_counting (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkListStore\" id=\"liststore1\"/>"
+    "  <object class=\"GtkListStore\" id=\"liststore2\"/>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkTreeView\" id=\"treeview1\">"
+    "        <property name=\"model\">liststore1</property>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkVBox\" id=\"vbox1\">"
+    "    <child>"
+    "      <object class=\"GtkLabel\" id=\"label1\"/>"
+    "      <packing>"
+    "        <property name=\"pack-type\">start</property>"
+    "      </packing>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  GObject *window, *treeview, *model;
+  
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  window = gtk_builder_get_object (builder, "window1");
+  treeview = gtk_builder_get_object (builder, "treeview1");
+  model = gtk_builder_get_object (builder, "liststore1");
+  g_object_unref (builder);
+
+  g_object_weak_ref (model, (GWeakNotify)model_weakref, NULL);
+
+  g_assert (model_freed == FALSE);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), NULL);
+  g_assert (model_freed == TRUE);
+  
+  gtk_widget_destroy (GTK_WIDGET (window));
+
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  g_object_unref (builder);
+}
+
+static void
+test_icon_factory (void)
+{
+  GtkBuilder *builder;
+  const gchar buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
+    "    <sources>"
+    "      <source stock-id=\"apple-red\" filename=\"apple-red.png\"/>"
+    "    </sources>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
+    "    <sources>"
+    "      <source stock-id=\"sliff\" direction=\"rtl\" state=\"active\""
+    "              size=\"menu\" filename=\"sloff.png\"/>"
+    "      <source stock-id=\"sliff\" direction=\"ltr\" state=\"selected\""
+    "              size=\"dnd\" filename=\"slurf.png\"/>"
+    "    </sources>"
+    "  </object>"
+    "</interface>";
+#if 0
+  const gchar buffer3[] =
+    "<interface>"
+    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
+    "    <invalid/>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer4[] =
+    "<interface>"
+    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
+    "    <sources>"
+    "      <invalid/>"
+    "    </sources>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer5[] =
+    "<interface>"
+    "  <object class=\"GtkIconFactory\" id=\"iconfactory1\">"
+    "    <sources>"
+    "      <source/>"
+    "    </sources>"
+    "  </object>"
+    "</interface>";
+  GError *error = NULL;
+#endif  
+  GObject *factory;
+  GtkIconSet *icon_set;
+  GtkIconSource *icon_source;
+  GtkWidget *image;
+  
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  factory = gtk_builder_get_object (builder, "iconfactory1");
+  g_assert (factory != NULL);
+
+  icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (factory), "apple-red");
+  g_assert (icon_set != NULL);
+  gtk_icon_factory_add_default (GTK_ICON_FACTORY (factory));
+  image = gtk_image_new_from_stock ("apple-red", GTK_ICON_SIZE_BUTTON);
+  g_assert (image != NULL);
+  g_object_ref_sink (image);
+  g_object_unref (image);
+
+  g_object_unref (builder);
+
+  builder = builder_new_from_string (buffer2, -1, NULL);
+  factory = gtk_builder_get_object (builder, "iconfactory1");
+  g_assert (factory != NULL);
+
+  icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (factory), "sliff");
+  g_assert (icon_set != NULL);
+  g_assert (g_slist_length (icon_set->sources) == 2);
+
+  icon_source = icon_set->sources->data;
+  g_assert (gtk_icon_source_get_direction (icon_source) == GTK_TEXT_DIR_RTL);
+  g_assert (gtk_icon_source_get_state (icon_source) == GTK_STATE_ACTIVE);
+  g_assert (gtk_icon_source_get_size (icon_source) == GTK_ICON_SIZE_MENU);
+  g_assert (g_str_has_suffix (gtk_icon_source_get_filename (icon_source), "sloff.png"));
+  
+  icon_source = icon_set->sources->next->data;
+  g_assert (gtk_icon_source_get_direction (icon_source) == GTK_TEXT_DIR_LTR);
+  g_assert (gtk_icon_source_get_state (icon_source) == GTK_STATE_SELECTED);
+  g_assert (gtk_icon_source_get_size (icon_source) == GTK_ICON_SIZE_DND);
+  g_assert (g_str_has_suffix (gtk_icon_source_get_filename (icon_source), "slurf.png"));
+
+  g_object_unref (builder);
+
+#if 0
+  error = NULL;
+  gtk_builder_add_from_string (builder, buffer3, -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_TAG));
+  g_error_free (error);
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, buffer4, -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_TAG));
+  g_error_free (error);
+
+  error = NULL;
+  gtk_builder_add_from_string (builder, buffer5, -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
+  g_error_free (error);
+#endif
+
+}
+
+typedef struct {
+  gboolean weight;
+  gboolean foreground;
+  gboolean underline;
+  gboolean size;
+  gboolean font_desc;
+  gboolean language;
+} FoundAttrs;
+
+static gboolean 
+filter_pango_attrs (PangoAttribute *attr, 
+                   gpointer        data)
+{
+  FoundAttrs *found = (FoundAttrs *)data;
+
+  if (attr->klass->type == PANGO_ATTR_WEIGHT)
+    found->weight = TRUE;
+  else if (attr->klass->type == PANGO_ATTR_FOREGROUND)
+    found->foreground = TRUE;
+  else if (attr->klass->type == PANGO_ATTR_UNDERLINE)
+    found->underline = TRUE;
+  /* Make sure optional start/end properties are working */
+  else if (attr->klass->type == PANGO_ATTR_SIZE && 
+          attr->start_index == 5 &&
+          attr->end_index   == 10)
+    found->size = TRUE;
+  else if (attr->klass->type == PANGO_ATTR_FONT_DESC)
+    found->font_desc = TRUE;
+  else if (attr->klass->type == PANGO_ATTR_LANGUAGE)
+    found->language = TRUE;
+
+  return TRUE;
+}
+
+static void
+test_pango_attributes (void)
+{
+  GtkBuilder *builder;
+  FoundAttrs found = { 0, };
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkLabel\" id=\"label1\">"
+    "    <attributes>"
+    "      <attribute name=\"weight\" value=\"PANGO_WEIGHT_BOLD\"/>"
+    "      <attribute name=\"foreground\" value=\"DarkSlateGray\"/>"
+    "      <attribute name=\"underline\" value=\"True\"/>"
+    "      <attribute name=\"size\" value=\"4\" start=\"5\" end=\"10\"/>"
+    "      <attribute name=\"font-desc\" value=\"Sans Italic 22\"/>"
+    "      <attribute name=\"language\" value=\"pt_BR\"/>"
+    "    </attributes>"
+    "  </object>"
+    "</interface>";
+  const gchar err_buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkLabel\" id=\"label1\">"
+    "    <attributes>"
+    "      <attribute name=\"weight\"/>"
+    "    </attributes>"
+    "  </object>"
+    "</interface>";
+  const gchar err_buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkLabel\" id=\"label1\">"
+    "    <attributes>"
+    "      <attribute name=\"weight\" value=\"PANGO_WEIGHT_BOLD\" unrecognized=\"True\"/>"
+    "    </attributes>"
+    "  </object>"
+    "</interface>";
+
+  GObject *label;
+  GError  *error = NULL;
+  PangoAttrList *attrs, *filtered;
+  
+  /* Test attributes are set */
+  builder = builder_new_from_string (buffer, -1, NULL);
+  label = gtk_builder_get_object (builder, "label1");
+  g_assert (label != NULL);
+
+  attrs = gtk_label_get_attributes (GTK_LABEL (label));
+  g_assert (attrs != NULL);
+
+  filtered = pango_attr_list_filter (attrs, filter_pango_attrs, &found);
+  g_assert (filtered);
+  pango_attr_list_unref (filtered);
+
+  g_assert (found.weight);
+  g_assert (found.foreground);
+  g_assert (found.underline);
+  g_assert (found.size);
+  g_assert (found.language);
+  g_assert (found.font_desc);
+
+  g_object_unref (builder);
+
+  /* Test errors are set */
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_string (builder, err_buffer1, -1, &error);
+  label = gtk_builder_get_object (builder, "label1");
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_MISSING_ATTRIBUTE));
+  g_object_unref (builder);
+  g_error_free (error);
+  error = NULL;
+
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_string (builder, err_buffer2, -1, &error);
+  label = gtk_builder_get_object (builder, "label1");
+
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
+  g_object_unref (builder);
+  g_error_free (error);
+}
+
+static void
+test_requires (void)
+{
+  GtkBuilder *builder;
+  GError     *error = NULL;
+  gchar      *buffer;
+  const gchar buffer_fmt[] =
+    "<interface>"
+    "  <requires lib=\"gtk+\" version=\"%d.%d\"/>"
+    "</interface>";
+
+  buffer = g_strdup_printf (buffer_fmt, GTK_MAJOR_VERSION, GTK_MINOR_VERSION + 1);
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_string (builder, buffer, -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_VERSION_MISMATCH));
+  g_object_unref (builder);
+  g_error_free (error);
+  g_free (buffer);
+}
+
+static void
+test_add_objects (void)
+{
+  GtkBuilder *builder;
+  GError *error;
+  gint ret;
+  GObject *obj;
+  GtkUIManager *manager;
+  GtkWidget *menubar;
+  GObject *menu, *label;
+  GList *children;
+  gchar *objects[2] = {"mainbox", NULL};
+  gchar *objects2[3] = {"mainbox", "window2", NULL};
+  gchar *objects3[3] = {"uimgr1", "menubar1"};
+  gchar *objects4[2] = {"uimgr1", NULL};
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window\">"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"mainbox\">"
+    "        <property name=\"visible\">True</property>"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"label1\">"
+    "            <property name=\"visible\">True</property>"
+    "            <property name=\"label\" translatable=\"no\">first label</property>"
+    "          </object>"
+    "        </child>"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"label2\">"
+    "            <property name=\"visible\">True</property>"
+    "            <property name=\"label\" translatable=\"no\">second label</property>"
+    "          </object>"
+    "          <packing>"
+    "            <property name=\"position\">1</property>"
+    "          </packing>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window2\">"
+    "    <child>"
+    "      <object class=\"GtkLabel\" id=\"label3\">"
+    "        <property name=\"label\" translatable=\"no\">second label</property>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "<interface/>";
+  const gchar buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkUIManager\" id=\"uimgr1\">"
+    "    <child>"
+    "      <object class=\"GtkActionGroup\" id=\"ag1\">"
+    "        <child>"
+    "          <object class=\"GtkAction\" id=\"file\">"
+    "            <property name=\"label\">_File</property>"
+    "          </object>"
+    "          <accelerator key=\"n\" modifiers=\"GDK_CONTROL_MASK\"/>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "    <ui>"
+    "      <menubar name=\"menubar1\">"
+    "        <menu action=\"file\">"
+    "        </menu>"
+    "      </menubar>"
+    "    </ui>"
+    "  </object>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <child>"
+    "      <object class=\"GtkMenuBar\" id=\"menubar1\" constructor=\"uimgr1\"/>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+
+  error = NULL;
+  builder = gtk_builder_new ();
+  ret = gtk_builder_add_objects_from_string (builder, buffer, -1, objects, &error);
+  g_assert (ret);
+  g_assert (error == NULL);
+  obj = gtk_builder_get_object (builder, "window");
+  g_assert (obj == NULL);
+  obj = gtk_builder_get_object (builder, "window2");
+  g_assert (obj == NULL);
+  obj = gtk_builder_get_object (builder, "mainbox");  
+  g_assert (GTK_IS_WIDGET (obj));
+  g_object_unref (builder);
+
+  error = NULL;
+  builder = gtk_builder_new ();
+  ret = gtk_builder_add_objects_from_string (builder, buffer, -1, objects2, &error);
+  g_assert (ret);
+  g_assert (error == NULL);
+  obj = gtk_builder_get_object (builder, "window");
+  g_assert (obj == NULL);
+  obj = gtk_builder_get_object (builder, "window2");
+  g_assert (GTK_IS_WINDOW (obj));
+  gtk_widget_destroy (GTK_WIDGET (obj));
+  obj = gtk_builder_get_object (builder, "mainbox");  
+  g_assert (GTK_IS_WIDGET (obj));
+  g_object_unref (builder);
+
+  /* test cherry picking a ui manager and menubar that depends on it */
+  error = NULL;
+  builder = gtk_builder_new ();
+  ret = gtk_builder_add_objects_from_string (builder, buffer2, -1, objects3, &error);
+  g_assert (ret);
+  obj = gtk_builder_get_object (builder, "uimgr1");
+  g_assert (GTK_IS_UI_MANAGER (obj));
+  obj = gtk_builder_get_object (builder, "file");
+  g_assert (GTK_IS_ACTION (obj));
+  obj = gtk_builder_get_object (builder, "menubar1");
+  g_assert (GTK_IS_MENU_BAR (obj));
+  menubar = GTK_WIDGET (obj);
+
+  children = gtk_container_get_children (GTK_CONTAINER (menubar));
+  menu = children->data;
+  g_assert (menu != NULL);
+  g_assert (GTK_IS_MENU_ITEM (menu));
+  g_assert (strcmp (gtk_widget_get_name (GTK_WIDGET (menu)), "file") == 0);
+  g_list_free (children);
+  label = G_OBJECT (gtk_bin_get_child (GTK_BIN (menu)));
+  g_assert (label != NULL);
+  g_assert (GTK_IS_LABEL (label));
+  g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
+
+  g_object_unref (builder);
+
+  /* test cherry picking just the ui manager */
+  error = NULL;
+  builder = gtk_builder_new ();
+  ret = gtk_builder_add_objects_from_string (builder, buffer2, -1, objects4, &error);
+  g_assert (ret);
+  obj = gtk_builder_get_object (builder, "uimgr1");
+  g_assert (GTK_IS_UI_MANAGER (obj));
+  manager = GTK_UI_MANAGER (obj);
+  obj = gtk_builder_get_object (builder, "file");
+  g_assert (GTK_IS_ACTION (obj));
+  menubar = gtk_ui_manager_get_widget (manager, "/menubar1");
+  g_assert (GTK_IS_MENU_BAR (menubar));
+
+  children = gtk_container_get_children (GTK_CONTAINER (menubar));
+  menu = children->data;
+  g_assert (menu != NULL);
+  g_assert (GTK_IS_MENU_ITEM (menu));
+  g_assert (strcmp (gtk_widget_get_name (GTK_WIDGET (menu)), "file") == 0);
+  g_list_free (children);
+  label = G_OBJECT (gtk_bin_get_child (GTK_BIN (menu)));
+  g_assert (label != NULL);
+  g_assert (GTK_IS_LABEL (label));
+  g_assert (strcmp (gtk_label_get_text (GTK_LABEL (label)), "File") == 0);
+
+  g_object_unref (builder);
+}
+
+static GtkWidget *
+get_parent_menubar (GtkWidget *menuitem)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *attach = NULL;
+
+  menu_shell = GTK_MENU_SHELL (gtk_widget_get_parent (menuitem));
+
+  g_assert (GTK_IS_MENU_SHELL (menu_shell));
+
+  while (menu_shell && !GTK_IS_MENU_BAR (menu_shell))
+    {
+      if (GTK_IS_MENU (menu_shell) && 
+         (attach = gtk_menu_get_attach_widget (GTK_MENU (menu_shell))) != NULL)
+       menu_shell = GTK_MENU_SHELL (gtk_widget_get_parent (attach));
+      else
+       menu_shell = NULL;
+    }
+
+  return menu_shell ? GTK_WIDGET (menu_shell) : NULL;
+}
+
+static void
+test_menus (void)
+{
+  const gchar *buffer =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <accel-groups>"
+    "      <group name=\"accelgroup1\"/>"
+    "    </accel-groups>"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"vbox1\">"
+    "        <property name=\"visible\">True</property>"
+    "        <property name=\"orientation\">vertical</property>"
+    "        <child>"
+    "          <object class=\"GtkMenuBar\" id=\"menubar1\">"
+    "            <property name=\"visible\">True</property>"
+    "            <child>"
+    "              <object class=\"GtkMenuItem\" id=\"menuitem1\">"
+    "                <property name=\"visible\">True</property>"
+    "                <property name=\"label\" translatable=\"yes\">_File</property>"
+    "                <property name=\"use_underline\">True</property>"
+    "                <child type=\"submenu\">"
+    "                  <object class=\"GtkMenu\" id=\"menu1\">"
+    "                    <property name=\"visible\">True</property>"
+    "                    <child>"
+    "                      <object class=\"GtkImageMenuItem\" id=\"imagemenuitem1\">"
+    "                        <property name=\"label\">gtk-new</property>"
+    "                        <property name=\"visible\">True</property>"
+    "                        <property name=\"use_stock\">True</property>"
+    "                        <property name=\"accel_group\">accelgroup1</property>"
+    "                      </object>"
+    "                    </child>"
+    "                  </object>"
+    "                </child>"
+    "              </object>"
+    "            </child>"
+    "          </object>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "<object class=\"GtkAccelGroup\" id=\"accelgroup1\"/>"
+    "</interface>";
+
+  const gchar *buffer1 =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window1\">"
+    "    <accel-groups>"
+    "      <group name=\"accelgroup1\"/>"
+    "    </accel-groups>"
+    "    <child>"
+    "      <object class=\"GtkVBox\" id=\"vbox1\">"
+    "        <property name=\"visible\">True</property>"
+    "        <property name=\"orientation\">vertical</property>"
+    "        <child>"
+    "          <object class=\"GtkMenuBar\" id=\"menubar1\">"
+    "            <property name=\"visible\">True</property>"
+    "            <child>"
+    "              <object class=\"GtkImageMenuItem\" id=\"imagemenuitem1\">"
+    "                <property name=\"visible\">True</property>"
+    "                <child>"
+    "                  <object class=\"GtkLabel\" id=\"custom1\">"
+    "                    <property name=\"visible\">True</property>"
+    "                    <property name=\"label\">a label</property>"
+    "                  </object>"
+    "                </child>"
+    "              </object>"
+    "            </child>"
+    "          </object>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "<object class=\"GtkAccelGroup\" id=\"accelgroup1\"/>"
+    "</interface>";
+  GtkBuilder *builder;
+  GtkWidget *child;
+  GtkWidget *window, *item;
+  GtkAccelGroup *accel_group;
+  GtkWidget *item_accel_label, *sample_accel_label, *sample_menu_item, *custom;
+
+  /* Check that the item has the correct accel label string set
+   */
+  builder = builder_new_from_string (buffer, -1, NULL);
+  window = (GtkWidget *)gtk_builder_get_object (builder, "window1");
+  item = (GtkWidget *)gtk_builder_get_object (builder, "imagemenuitem1");
+  accel_group = (GtkAccelGroup *)gtk_builder_get_object (builder, "accelgroup1");
+
+  gtk_widget_show_all (window);
+
+  sample_menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, accel_group);
+
+  child = gtk_bin_get_child (GTK_BIN (sample_menu_item));
+  g_assert (child);
+  g_assert (GTK_IS_ACCEL_LABEL (child));
+  sample_accel_label = child;
+  gtk_widget_show (sample_accel_label);
+
+  child = gtk_bin_get_child (GTK_BIN (item));
+  g_assert (child);
+  g_assert (GTK_IS_ACCEL_LABEL (child));
+  item_accel_label = child;
+
+  gtk_accel_label_refetch (GTK_ACCEL_LABEL (sample_accel_label));
+  gtk_accel_label_refetch (GTK_ACCEL_LABEL (item_accel_label));
+
+  g_assert (gtk_label_get_text (GTK_LABEL (sample_accel_label)) != NULL);
+  g_assert (gtk_label_get_text (GTK_LABEL (item_accel_label)) != NULL);
+  g_assert (strcmp (gtk_label_get_text (GTK_LABEL (item_accel_label)),
+                   gtk_label_get_text (GTK_LABEL (sample_accel_label))) == 0);
+
+  /* Check the menu hierarchy worked here  */
+  g_assert (get_parent_menubar (item));
+
+  gtk_widget_destroy (GTK_WIDGET (window));
+  gtk_widget_destroy (sample_menu_item);
+  g_object_unref (builder);
+
+
+  /* Check that we can add alien children to menu items via normal
+   * GtkContainer apis.
+   */
+  builder = builder_new_from_string (buffer1, -1, NULL);
+  window = (GtkWidget *)gtk_builder_get_object (builder, "window1");
+  item = (GtkWidget *)gtk_builder_get_object (builder, "imagemenuitem1");
+  custom = (GtkWidget *)gtk_builder_get_object (builder, "custom1");
+
+  g_assert (gtk_widget_get_parent (custom) == item);
+
+  gtk_widget_destroy (GTK_WIDGET (window));
+  g_object_unref (builder);
+
+}
+
+
+static void 
+test_file (const gchar *filename)
+{
+  GtkBuilder *builder;
+  GError *error = NULL;
+  GSList *l, *objects;
+
+  builder = gtk_builder_new ();
+
+  if (!gtk_builder_add_from_file (builder, filename, &error))
+    {
+      g_error ("%s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  objects = gtk_builder_get_objects (builder);
+  for (l = objects; l; l = l->next)
+    {
+      GObject *obj = (GObject*)l->data;
+
+      if (GTK_IS_DIALOG (obj))
+       {
+         g_print ("Running dialog %s.\n",
+                  gtk_widget_get_name (GTK_WIDGET (obj)));
+         gtk_dialog_run (GTK_DIALOG (obj));
+       }
+      else if (GTK_IS_WINDOW (obj))
+       {
+         g_signal_connect (obj, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+         g_print ("Showing %s.\n",
+                  gtk_widget_get_name (GTK_WIDGET (obj)));
+         gtk_widget_show_all (GTK_WIDGET (obj));
+       }
+    }
+
+  gtk_main ();
+
+  g_object_unref (builder);
+  builder = NULL;
+}
+
+static void
+test_message_area (void)
+{
+  GtkBuilder *builder;
+  GObject *obj, *obj1;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkInfoBar\" id=\"infobar1\">"
+    "    <child internal-child=\"content_area\">"
+    "      <object class=\"GtkHBox\" id=\"contentarea1\">"
+    "        <child>"
+    "          <object class=\"GtkLabel\" id=\"content\">"
+    "            <property name=\"label\" translatable=\"yes\">Message</property>"
+    "          </object>"
+    "          <packing>"
+    "            <property name='expand'>False</property>"
+    "          </packing>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "    <child internal-child=\"action_area\">"
+    "      <object class=\"GtkVButtonBox\" id=\"actionarea1\">"
+    "        <child>"
+    "          <object class=\"GtkButton\" id=\"button_ok\">"
+    "            <property name=\"label\">gtk-ok</property>"
+    "            <property name=\"use-stock\">yes</property>"
+    "          </object>"
+    "        </child>"
+    "      </object>"
+    "    </child>"
+    "    <action-widgets>"
+    "      <action-widget response=\"1\">button_ok</action-widget>"
+    "    </action-widgets>"
+    "  </object>"
+    "</interface>";
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  obj = gtk_builder_get_object (builder, "infobar1");
+  g_assert (GTK_IS_INFO_BAR (obj));
+  obj1 = gtk_builder_get_object (builder, "content");
+  g_assert (GTK_IS_LABEL (obj1));
+  g_assert (gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (obj1))) == GTK_WIDGET (obj));
+
+  obj1 = gtk_builder_get_object (builder, "button_ok");
+  g_assert (GTK_IS_BUTTON (obj1));
+  g_assert (gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (obj1))) == GTK_WIDGET (obj));
+
+  g_object_unref (builder);
+}
+
+static void
+test_gmenu (void)
+{
+  GtkBuilder *builder;
+  GObject *obj, *obj1;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window\">"
+    "  </object>"
+    "  <menu id='edit-menu'>"
+    "    <section>"
+    "      <item>"
+    "        <attribute name='label'>Undo</attribute>"
+    "        <attribute name='action'>undo</attribute>"
+    "      </item>"
+    "      <item>"
+    "        <attribute name='label'>Redo</attribute>"
+    "        <attribute name='action'>redo</attribute>"
+    "      </item>"
+    "    </section>"
+    "    <section></section>"
+    "    <section>"
+    "      <attribute name='label'>Copy &amp; Paste</attribute>"
+    "      <item>"
+    "        <attribute name='label'>Cut</attribute>"
+    "        <attribute name='action'>cut</attribute>"
+    "      </item>"
+    "      <item>"
+    "        <attribute name='label'>Copy</attribute>"
+    "        <attribute name='action'>copy</attribute>"
+    "      </item>"
+    "      <item>"
+    "        <attribute name='label'>Paste</attribute>"
+    "        <attribute name='action'>paste</attribute>"
+    "      </item>"
+    "    </section>"
+    "    <item><link name='section' id='blargh'>"
+    "      <item>"
+    "        <attribute name='label'>Bold</attribute>"
+    "        <attribute name='action'>bold</attribute>"
+    "      </item>"
+    "      <submenu>"
+    "        <attribute name='label'>Language</attribute>"
+    "        <item>"
+    "          <attribute name='label'>Latin</attribute>"
+    "          <attribute name='action'>lang</attribute>"
+    "          <attribute name='target'>'latin'</attribute>"
+    "        </item>"
+    "        <item>"
+    "          <attribute name='label'>Greek</attribute>"
+    "          <attribute name='action'>lang</attribute>"
+    "          <attribute name='target'>'greek'</attribute>"
+    "        </item>"
+    "        <item>"
+    "          <attribute name='label'>Urdu</attribute>"
+    "          <attribute name='action'>lang</attribute>"
+    "          <attribute name='target'>'urdu'</attribute>"
+    "        </item>"
+    "      </submenu>"
+    "    </link></item>"
+    "  </menu>"
+    "</interface>";
+
+  builder = builder_new_from_string (buffer, -1, NULL);
+  obj = gtk_builder_get_object (builder, "window");
+  g_assert (GTK_IS_WINDOW (obj));
+  obj1 = gtk_builder_get_object (builder, "edit-menu");
+  g_assert (G_IS_MENU_MODEL (obj1));
+  obj1 = gtk_builder_get_object (builder, "blargh");
+  g_assert (G_IS_MENU_MODEL (obj1));
+  g_object_unref (builder);
+}
+
+static void
+test_level_bar (void)
+{
+  GtkBuilder *builder;
+  GError *error = NULL;
+  GObject *obj, *obj1;
+  const gchar buffer1[] =
+    "<interface>"
+    "  <object class=\"GtkWindow\" id=\"window\">"
+    "    <child>"
+    "      <object class=\"GtkLevelBar\" id=\"levelbar\">"
+    "        <property name=\"value\">4.70</property>"
+    "        <property name=\"min-value\">2</property>"
+    "        <property name=\"max-value\">5</property>"
+    "        <offsets>"
+    "          <offset name=\"low\" value=\"2.25\"/>"
+    "          <offset name=\"custom\" value=\"3\"/>"
+    "          <offset name=\"high\" value=\"3\"/>"
+    "        </offsets>"
+    "      </object>"
+    "    </child>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer2[] =
+    "<interface>"
+    "  <object class=\"GtkLevelBar\" id=\"levelbar\">"
+    "    <offsets>"
+    "      <offset name=\"low\" bogus_attr=\"foo\"/>"
+    "    </offsets>"
+    "  </object>"
+    "</interface>";
+  const gchar buffer3[] =
+    "<interface>"
+    "  <object class=\"GtkLevelBar\" id=\"levelbar\">"
+    "    <offsets>"
+    "      <offset name=\"low\" value=\"1\"/>"
+    "    </offsets>"
+    "    <bogus_tag>"
+    "    </bogus_tag>"
+    "  </object>"
+    "</interface>";
+
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_string (builder, buffer1, -1, &error);
+  g_assert (error == NULL);
+
+  obj = gtk_builder_get_object (builder, "window");
+  g_assert (GTK_IS_WINDOW (obj));
+  obj1 = gtk_builder_get_object (builder, "levelbar");
+  g_assert (GTK_IS_LEVEL_BAR (obj1));
+  g_object_unref (builder);
+
+  error = NULL;
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_string (builder, buffer2, -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_INVALID_ATTRIBUTE));
+  g_error_free (error);
+  g_object_unref (builder);
+
+  error = NULL;
+  builder = gtk_builder_new ();
+  gtk_builder_add_from_string (builder, buffer3, -1, &error);
+  g_assert (g_error_matches (error,
+                             GTK_BUILDER_ERROR,
+                             GTK_BUILDER_ERROR_UNHANDLED_TAG));
+  g_error_free (error);
+  g_object_unref (builder);
+}
+
+static GObject *external_object = NULL, *external_object_swapped = NULL;
+
+void
+on_button_clicked (GtkButton *button, GObject *data)
+{
+  external_object = data;
+}
+
+void
+on_button_clicked_swapped (GObject *data, GtkButton *button)
+{
+  external_object_swapped = data;
+}
+
+static void
+test_expose_object (void)
+{
+  GtkBuilder *builder;
+  GError *error = NULL;
+  GtkWidget *image;
+  GObject *obj;
+  const gchar buffer[] =
+    "<interface>"
+    "  <object class=\"GtkButton\" id=\"button\">"
+    "    <property name=\"image\">external_image</property>"
+    "    <signal name=\"clicked\" handler=\"on_button_clicked\" object=\"builder\" swapped=\"no\"/>"
+    "    <signal name=\"clicked\" handler=\"on_button_clicked_swapped\" object=\"builder\"/>"
+    "  </object>"
+    "</interface>";
+
+  image = gtk_image_new ();
+  builder = gtk_builder_new ();
+  gtk_builder_expose_object (builder, "external_image", G_OBJECT (image));
+  gtk_builder_expose_object (builder, "builder", G_OBJECT (builder));
+  gtk_builder_add_from_string (builder, buffer, -1, &error);
+  g_assert (error == NULL);
+
+  obj = gtk_builder_get_object (builder, "button");
+  g_assert (GTK_IS_BUTTON (obj));
+
+  g_assert (gtk_button_get_image (GTK_BUTTON (obj)) == image);
+
+  /* Connect signals and fake clicked event */
+  gtk_builder_connect_signals (builder, NULL);
+  gtk_button_clicked (GTK_BUTTON (obj));
+
+  g_assert (external_object == G_OBJECT (builder));
+  g_assert (external_object_swapped == G_OBJECT (builder));
+}
+
+int
+main (int argc, char **argv)
+{
+  /* initialize test program */
+  gtk_test_init (&argc, &argv);
+
+  if (argc > 1)
+    {
+      test_file (argv[1]);
+      return 0;
+    }
+
+  g_test_add_func ("/Builder/Parser", test_parser);
+  g_test_add_func ("/Builder/Types", test_types);
+  g_test_add_func ("/Builder/Construct-Only Properties", test_construct_only_property);
+  g_test_add_func ("/Builder/Children", test_children);
+  g_test_add_func ("/Builder/Child Properties", test_child_properties);
+  g_test_add_func ("/Builder/Object Properties", test_object_properties);
+  g_test_add_func ("/Builder/Notebook", test_notebook);
+  g_test_add_func ("/Builder/Domain", test_domain);
+  g_test_add_func ("/Builder/Signal Autoconnect", test_connect_signals);
+  g_test_add_func ("/Builder/UIManager Simple", test_uimanager_simple);
+  g_test_add_func ("/Builder/Spin Button", test_spin_button);
+  g_test_add_func ("/Builder/SizeGroup", test_sizegroup);
+  g_test_add_func ("/Builder/ListStore", test_list_store);
+  g_test_add_func ("/Builder/TreeStore", test_tree_store);
+  g_test_add_func ("/Builder/TreeView Column", test_treeview_column);
+  g_test_add_func ("/Builder/IconView", test_icon_view);
+  g_test_add_func ("/Builder/ComboBox", test_combo_box);
+#if 0
+  g_test_add_func ("/Builder/ComboBox Entry", test_combo_box_entry);
+#endif
+  g_test_add_func ("/Builder/CellView", test_cell_view);
+  g_test_add_func ("/Builder/Dialog", test_dialog);
+  g_test_add_func ("/Builder/Accelerators", test_accelerators);
+  g_test_add_func ("/Builder/Widget", test_widget);
+  g_test_add_func ("/Builder/Value From String", test_value_from_string);
+  g_test_add_func ("/Builder/Reference Counting", test_reference_counting);
+  g_test_add_func ("/Builder/Window", test_window);
+  g_test_add_func ("/Builder/IconFactory", test_icon_factory);
+  g_test_add_func ("/Builder/PangoAttributes", test_pango_attributes);
+  g_test_add_func ("/Builder/Requires", test_requires);
+  g_test_add_func ("/Builder/AddObjects", test_add_objects);
+  g_test_add_func ("/Builder/Menus", test_menus);
+  g_test_add_func ("/Builder/MessageArea", test_message_area);
+  g_test_add_func ("/Builder/MessageDialog", test_message_dialog);
+  g_test_add_func ("/Builder/GMenu", test_gmenu);
+  g_test_add_func ("/Builder/LevelBar", test_level_bar);
+  g_test_add_func ("/Builder/Expose Object", test_expose_object);
+
+  return g_test_run();
+}
+
diff --git a/testsuite/gtk/cellarea.c b/testsuite/gtk/cellarea.c
new file mode 100644 (file)
index 0000000..98072ed
--- /dev/null
@@ -0,0 +1,863 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Author: Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+/* tests related to handling of the cell-area property in
+ * GtkCellLayout implementations
+ */
+
+/* test that we have a cell area after new() */
+static void
+test_iconview_new (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  view = gtk_icon_view_new ();
+
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == gtk_icon_view_get_item_orientation (GTK_ICON_VIEW (view)));
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that new_with_area() keeps the provided area */
+static void
+test_iconview_new_with_area (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  view = gtk_icon_view_new_with_area (area);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that g_object_new keeps the provided area */
+static void
+test_iconview_object_new (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
+  view = g_object_new (GTK_TYPE_ICON_VIEW, "cell-area", area, NULL);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == gtk_icon_view_get_item_orientation (GTK_ICON_VIEW (view)));
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+typedef GtkIconView MyIconView;
+typedef GtkIconViewClass MyIconViewClass;
+
+GType my_icon_view_get_type (void);
+
+G_DEFINE_TYPE (MyIconView, my_icon_view, GTK_TYPE_ICON_VIEW)
+
+static void
+my_icon_view_class_init (MyIconViewClass *klass)
+{
+}
+
+static gint subclass_init;
+
+static void
+my_icon_view_init (MyIconView *view)
+{
+  GtkCellArea *area;
+
+  if (subclass_init == 0)
+    {
+      /* do nothing to area */
+    }
+  else if (subclass_init == 1)
+    {
+      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+      g_assert (GTK_IS_CELL_AREA_BOX (area));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
+    }
+}
+
+/* test that an iconview subclass has an area */
+static void
+test_iconview_subclass0 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  view = g_object_new (my_icon_view_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that an iconview subclass keeps the provided area */
+static void
+test_iconview_subclass1 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  area = gtk_cell_area_box_new ();
+  view = g_object_new (my_icon_view_get_type (), "cell-area", area, NULL);
+  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test we can access the area in subclass init */
+static void
+test_iconview_subclass2 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 1;
+
+  view = g_object_new (my_icon_view_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test we get a warning if an area is provided, but ignored */
+static void
+test_iconview_subclass3 (void)
+{
+  subclass_init = 1;
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+    {
+      GtkWidget *view;
+      GtkCellArea *area;
+
+      area = gtk_cell_area_box_new ();
+      view = g_object_new (my_icon_view_get_type (), "cell-area", area, NULL);
+      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+      g_object_ref_sink (view);
+      g_object_unref (view);
+
+      exit (0);
+    }
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*ignoring construct property*");
+}
+
+/* test that we have a cell area after new() */
+static void
+test_combobox_new (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  view = gtk_combo_box_new ();
+
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that new_with_area() keeps the provided area */
+static void
+test_combobox_new_with_area (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  view = gtk_combo_box_new_with_area (area);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that g_object_new keeps the provided area */
+static void
+test_combobox_object_new (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
+  view = g_object_new (GTK_TYPE_COMBO_BOX, "cell-area", area, NULL);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+typedef GtkComboBox MyComboBox;
+typedef GtkComboBoxClass MyComboBoxClass;
+
+GType my_combo_box_get_type (void);
+
+G_DEFINE_TYPE (MyComboBox, my_combo_box, GTK_TYPE_COMBO_BOX)
+
+static void
+my_combo_box_class_init (MyComboBoxClass *klass)
+{
+}
+
+static void
+my_combo_box_init (MyComboBox *view)
+{
+  GtkCellArea *area;
+
+  if (subclass_init == 0)
+    {
+      /* do nothing to area */
+    }
+  else if (subclass_init == 1)
+    {
+      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+      g_assert (GTK_IS_CELL_AREA_BOX (area));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
+    }
+}
+
+/* test that a combobox subclass has an area */
+static void
+test_combobox_subclass0 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  view = g_object_new (my_combo_box_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that a combobox subclass keeps the provided area */
+static void
+test_combobox_subclass1 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  area = gtk_cell_area_box_new ();
+  view = g_object_new (my_combo_box_get_type (), "cell-area", area, NULL);
+  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test we can access the area in subclass init */
+static void
+test_combobox_subclass2 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 1;
+
+  view = g_object_new (my_combo_box_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test we get a warning if an area is provided, but ignored */
+static void
+test_combobox_subclass3 (void)
+{
+  subclass_init = 1;
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+    {
+      GtkWidget *view;
+      GtkCellArea *area;
+
+      area = gtk_cell_area_box_new ();
+      view = g_object_new (my_combo_box_get_type (), "cell-area", area, NULL);
+      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+      g_object_ref_sink (view);
+      g_object_unref (view);
+
+      exit (0);
+    }
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*ignoring construct property*");
+}
+
+/* test that we have a cell area after new() */
+static void
+test_cellview_new (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  view = gtk_cell_view_new ();
+
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that new_with_context() keeps the provided area */
+static void
+test_cellview_new_with_context (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+  GtkCellAreaContext *context;
+
+  area = gtk_cell_area_box_new ();
+  context = gtk_cell_area_create_context (area);
+  view = gtk_cell_view_new_with_context (area, context);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that g_object_new keeps the provided area */
+static void
+test_cellview_object_new (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
+  view = g_object_new (GTK_TYPE_CELL_VIEW, "cell-area", area, NULL);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)) == area);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+typedef GtkCellView MyCellView;
+typedef GtkCellViewClass MyCellViewClass;
+
+GType my_cell_view_get_type (void);
+
+G_DEFINE_TYPE (MyCellView, my_cell_view, GTK_TYPE_CELL_VIEW)
+
+static void
+my_cell_view_class_init (MyCellViewClass *klass)
+{
+}
+
+static void
+my_cell_view_init (MyCellView *view)
+{
+  GtkCellArea *area;
+
+  if (subclass_init == 0)
+    {
+      /* do nothing to area */
+    }
+  else if (subclass_init == 1)
+    {
+      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+      g_assert (GTK_IS_CELL_AREA_BOX (area));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
+    }
+}
+
+/* test that a cellview subclass has an area */
+static void
+test_cellview_subclass0 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  view = g_object_new (my_cell_view_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test that a cellview subclass keeps the provided area */
+static void
+test_cellview_subclass1 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  area = gtk_cell_area_box_new ();
+  view = g_object_new (my_cell_view_get_type (), "cell-area", area, NULL);
+  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test we can access the area in subclass init */
+static void
+test_cellview_subclass2 (void)
+{
+  GtkWidget *view;
+  GtkCellArea *area;
+
+  subclass_init = 1;
+
+  view = g_object_new (my_cell_view_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+  g_object_ref_sink (view);
+  g_object_unref (view);
+}
+
+/* test we get a warning if an area is provided, but ignored */
+static void
+test_cellview_subclass3 (void)
+{
+  subclass_init = 1;
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+    {
+      GtkWidget *view;
+      GtkCellArea *area;
+
+      area = gtk_cell_area_box_new ();
+      view = g_object_new (my_cell_view_get_type (), "cell-area", area, NULL);
+      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (view)));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+      g_object_ref_sink (view);
+      g_object_unref (view);
+
+      exit (0);
+    }
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*ignoring construct property*");
+}
+
+/* test that we have a cell area after new() */
+static void
+test_column_new (void)
+{
+  GtkTreeViewColumn *col;
+  GtkCellArea *area;
+
+  col = gtk_tree_view_column_new ();
+
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+
+  g_object_ref_sink (col);
+  g_object_unref (col);
+}
+
+/* test that new_with_area() keeps the provided area */
+static void
+test_column_new_with_area (void)
+{
+  GtkTreeViewColumn *col;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  col = gtk_tree_view_column_new_with_area (area);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)) == area);
+
+  g_object_ref_sink (col);
+  g_object_unref (col);
+}
+
+/* test that g_object_new keeps the provided area */
+static void
+test_column_object_new (void)
+{
+  GtkTreeViewColumn *col;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
+  col = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN, "cell-area", area, NULL);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)) == area);
+
+  g_object_ref_sink (col);
+  g_object_unref (col);
+}
+
+typedef GtkTreeViewColumn MyTreeViewColumn;
+typedef GtkTreeViewColumnClass MyTreeViewColumnClass;
+
+GType my_tree_view_column_get_type (void);
+
+G_DEFINE_TYPE (MyTreeViewColumn, my_tree_view_column, GTK_TYPE_TREE_VIEW_COLUMN)
+
+static void
+my_tree_view_column_class_init (MyTreeViewColumnClass *klass)
+{
+}
+
+static void
+my_tree_view_column_init (MyTreeViewColumn *col)
+{
+  GtkCellArea *area;
+
+  if (subclass_init == 0)
+    {
+      /* do nothing to area */
+    }
+  else if (subclass_init == 1)
+    {
+      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
+      g_assert (GTK_IS_CELL_AREA_BOX (area));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
+    }
+}
+
+/* test that a column subclass has an area */
+static void
+test_column_subclass0 (void)
+{
+  GtkTreeViewColumn *col;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  col = g_object_new (my_tree_view_column_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (col);
+  g_object_unref (col);
+}
+
+/* test that a column subclass keeps the provided area */
+static void
+test_column_subclass1 (void)
+{
+  GtkTreeViewColumn *col;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  area = gtk_cell_area_box_new ();
+  col = g_object_new (my_tree_view_column_get_type (), "cell-area", area, NULL);
+  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (col);
+  g_object_unref (col);
+}
+
+/* test we can access the area in subclass init */
+static void
+test_column_subclass2 (void)
+{
+  GtkTreeViewColumn *col;
+  GtkCellArea *area;
+
+  subclass_init = 1;
+
+  col = g_object_new (my_tree_view_column_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+  g_object_ref_sink (col);
+  g_object_unref (col);
+}
+
+/* test we get a warning if an area is provided, but ignored */
+static void
+test_column_subclass3 (void)
+{
+  subclass_init = 1;
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+    {
+      GtkTreeViewColumn *col;
+      GtkCellArea *area;
+
+      area = gtk_cell_area_box_new ();
+      col = g_object_new (my_tree_view_column_get_type (), "cell-area", area, NULL);
+      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (col)));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+      g_object_ref_sink (col);
+      g_object_unref (col);
+
+      exit (0);
+    }
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*ignoring construct property*");
+}
+
+/* test that we have a cell area after new() */
+static void
+test_completion_new (void)
+{
+  GtkEntryCompletion *c;
+  GtkCellArea *area;
+
+  c = gtk_entry_completion_new ();
+
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+
+  g_object_ref_sink (c);
+  g_object_unref (c);
+}
+
+/* test that new_with_area() keeps the provided area */
+static void
+test_completion_new_with_area (void)
+{
+  GtkEntryCompletion *c;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  c = gtk_entry_completion_new_with_area (area);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)) == area);
+
+  g_object_ref_sink (c);
+  g_object_unref (c);
+}
+
+/* test that g_object_new keeps the provided area */
+static void
+test_completion_object_new (void)
+{
+  GtkEntryCompletion *c;
+  GtkCellArea *area;
+
+  area = gtk_cell_area_box_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
+  c = g_object_new (GTK_TYPE_ENTRY_COMPLETION, "cell-area", area, NULL);
+  g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)) == area);
+
+  g_object_ref_sink (c);
+  g_object_unref (c);
+}
+
+typedef GtkEntryCompletion MyEntryCompletion;
+typedef GtkEntryCompletionClass MyEntryCompletionClass;
+
+GType my_entry_completion_get_type (void);
+
+G_DEFINE_TYPE (MyEntryCompletion, my_entry_completion, GTK_TYPE_ENTRY_COMPLETION)
+
+static void
+my_entry_completion_class_init (MyEntryCompletionClass *klass)
+{
+}
+
+static void
+my_entry_completion_init (MyEntryCompletion *c)
+{
+  GtkCellArea *area;
+
+  if (subclass_init == 0)
+    {
+      /* do nothing to area */
+    }
+  else if (subclass_init == 1)
+    {
+      area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
+      g_assert (GTK_IS_CELL_AREA_BOX (area));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+      gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_VERTICAL);
+    }
+}
+
+/* test that a completion subclass has an area */
+static void
+test_completion_subclass0 (void)
+{
+  GtkEntryCompletion *c;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  c = g_object_new (my_entry_completion_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (c);
+  g_object_unref (c);
+}
+
+/* test that a completion subclass keeps the provided area */
+static void
+test_completion_subclass1 (void)
+{
+  GtkEntryCompletion *c;
+  GtkCellArea *area;
+
+  subclass_init = 0;
+
+  area = gtk_cell_area_box_new ();
+  c = g_object_new (my_entry_completion_get_type (), "cell-area", area, NULL);
+  g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_HORIZONTAL);
+
+  g_object_ref_sink (c);
+  g_object_unref (c);
+}
+
+/* test we can access the area in subclass init */
+static void
+test_completion_subclass2 (void)
+{
+  GtkEntryCompletion *c;
+  GtkCellArea *area;
+
+  subclass_init = 1;
+
+  c = g_object_new (my_entry_completion_get_type (), NULL);
+  area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
+  g_assert (GTK_IS_CELL_AREA_BOX (area));
+  g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+  g_object_ref_sink (c);
+  g_object_unref (c);
+}
+
+/* test we get a warning if an area is provided, but ignored */
+static void
+test_completion_subclass3 (void)
+{
+  subclass_init = 1;
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+    {
+      GtkEntryCompletion *c;
+      GtkCellArea *area;
+
+      area = gtk_cell_area_box_new ();
+      c = g_object_new (my_entry_completion_get_type (), "cell-area", area, NULL);
+      g_assert (area == gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)));
+      g_assert (gtk_orientable_get_orientation (GTK_ORIENTABLE (area)) == GTK_ORIENTATION_VERTICAL);
+
+      g_object_ref_sink (c);
+      g_object_unref (c);
+
+      exit (0);
+    }
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*ignoring construct property*");
+}
+
+int
+main (int argc, char *argv[])
+{
+  gtk_test_init (&argc, &argv);
+  g_test_bug_base ("http://bugzilla.gnome.org/");
+  gtk_test_register_all_types();
+
+  g_test_add_func ("/tests/iconview-new", test_iconview_new);
+  g_test_add_func ("/tests/iconview-new-with-area", test_iconview_new_with_area);
+  g_test_add_func ("/tests/iconview-object-new", test_iconview_object_new);
+  g_test_add_func ("/tests/iconview-subclass0", test_iconview_subclass0);
+  g_test_add_func ("/tests/iconview-subclass1", test_iconview_subclass1);
+  g_test_add_func ("/tests/iconview-subclass2", test_iconview_subclass2);
+  g_test_add_func ("/tests/iconview-subclass3", test_iconview_subclass3);
+
+  g_test_add_func ("/tests/combobox-new", test_combobox_new);
+  g_test_add_func ("/tests/combobox-new-with-area", test_combobox_new_with_area);
+  g_test_add_func ("/tests/combobox-object-new", test_combobox_object_new);
+  g_test_add_func ("/tests/combobox-subclass0", test_combobox_subclass0);
+  g_test_add_func ("/tests/combobox-subclass1", test_combobox_subclass1);
+  g_test_add_func ("/tests/combobox-subclass2", test_combobox_subclass2);
+  g_test_add_func ("/tests/combobox-subclass3", test_combobox_subclass3);
+
+  g_test_add_func ("/tests/cellview-new", test_cellview_new);
+  g_test_add_func ("/tests/cellview-new-with-context", test_cellview_new_with_context);
+  g_test_add_func ("/tests/cellview-object-new", test_cellview_object_new);
+  g_test_add_func ("/tests/cellview-subclass0", test_cellview_subclass0);
+  g_test_add_func ("/tests/cellview-subclass1", test_cellview_subclass1);
+  g_test_add_func ("/tests/cellview-subclass2", test_cellview_subclass2);
+  g_test_add_func ("/tests/cellview-subclass3", test_cellview_subclass3);
+
+  g_test_add_func ("/tests/column-new", test_column_new);
+  g_test_add_func ("/tests/column-new-with-area", test_column_new_with_area);
+  g_test_add_func ("/tests/column-object-new", test_column_object_new);
+  g_test_add_func ("/tests/column-subclass0", test_column_subclass0);
+  g_test_add_func ("/tests/column-subclass1", test_column_subclass1);
+  g_test_add_func ("/tests/column-subclass2", test_column_subclass2);
+  g_test_add_func ("/tests/column-subclass3", test_column_subclass3);
+
+  g_test_add_func ("/tests/completion-new", test_completion_new);
+  g_test_add_func ("/tests/completion-new-with-area", test_completion_new_with_area);
+  g_test_add_func ("/tests/completion-object-new", test_completion_object_new);
+  g_test_add_func ("/tests/completion-subclass0", test_completion_subclass0);
+  g_test_add_func ("/tests/completion-subclass1", test_completion_subclass1);
+  g_test_add_func ("/tests/completion-subclass2", test_completion_subclass2);
+  g_test_add_func ("/tests/completion-subclass3", test_completion_subclass3);
+
+  return g_test_run();
+}
diff --git a/testsuite/gtk/crossingevents.c b/testsuite/gtk/crossingevents.c
new file mode 100644 (file)
index 0000000..be210f3
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ * crossingevents.c: A test for crossing events
+ *
+ * Copyright (C) 2008 Cody Russell
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+#include <string.h>
+
+typedef struct {
+  GtkWidget *window;
+  GtkWidget *eventbox;
+  GtkWidget *frame;
+  GtkWidget *button;
+  GtkWidget *check;
+  gboolean   events_connected;
+  GQueue    *queue;
+} CrossingTest;
+
+typedef struct {
+  gboolean entered;
+  gchar *name;
+  gboolean synthesized;
+  GdkCrossingMode mode;
+  GdkNotifyType detail;
+} CrossingEventData;
+
+#define SLEEP_DURATION    100
+
+void start_events (CrossingTest *test);
+void stop_events (CrossingTest *test);
+
+static gboolean
+sleep_timeout_cb (gpointer data)
+{
+  gtk_main_quit ();
+  return FALSE;
+}
+
+static void
+sleep_in_main_loop (double fraction)
+{
+  /* process all pending idles and events */
+  while (g_main_context_pending (NULL))
+    g_main_context_iteration (NULL, FALSE);
+  /* sleeping probably isn't strictly necessary here */
+  gdk_threads_add_timeout_full (G_MAXINT, fraction * SLEEP_DURATION, sleep_timeout_cb, NULL, NULL);
+  gtk_main ();
+  /* process any pending idles or events that arrived during sleep */
+  while (g_main_context_pending (NULL))
+    g_main_context_iteration (NULL, FALSE);
+}
+
+void
+set_cursor (GtkWidget *widget)
+{
+  int x, y, w, h;
+
+  gdk_window_get_origin (widget->window, &x, &y);
+
+  x += widget->allocation.x;
+  y += widget->allocation.y;
+  w = widget->allocation.width;
+  h = widget->allocation.height;
+
+  gdk_display_warp_pointer (gtk_widget_get_display (widget),
+                           gtk_widget_get_screen (widget),
+                           x + w / 2,
+                           y + h / 2);
+
+  sleep_in_main_loop (0.5);
+}
+
+static gboolean
+on_enter (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
+{
+  CrossingTest *test = (CrossingTest*)user_data;
+
+  CrossingEventData *evt = g_slice_new0 (CrossingEventData);
+  evt->entered = TRUE;
+  evt->name = g_strdup (gtk_widget_get_name (widget));
+  evt->synthesized = event->send_event;
+  evt->mode = event->mode;
+  evt->detail = event->detail;
+
+  if (!test->queue)
+    test->queue = g_queue_new ();
+
+  g_queue_push_tail (test->queue, evt);
+
+  return FALSE;
+}
+
+static gboolean
+on_leave (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
+{
+  CrossingTest *test = (CrossingTest*)user_data;
+
+  CrossingEventData *evt = g_slice_new0 (CrossingEventData);
+  evt->entered = FALSE;
+  evt->name = g_strdup (gtk_widget_get_name (widget));
+  evt->synthesized = event->send_event;
+  evt->mode = event->mode;
+  evt->detail = event->detail;
+
+  if (!test->queue)
+    test->queue = g_queue_new ();
+
+  g_queue_push_tail (test->queue, evt);
+
+  return FALSE;
+}
+
+static void
+on_check_toggled (GtkWidget *toggle, GtkWidget *button)
+{
+  gtk_widget_set_sensitive (button, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)));
+}
+
+static void
+sensitivity_setup (CrossingTest *test,
+                  gconstpointer user_data)
+{
+  GtkWidget *frame;
+
+  test->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_name (test->window, "W");
+  frame = gtk_frame_new ("Crossing Events");
+  test->eventbox = gtk_event_box_new ();
+  gtk_widget_set_name (test->eventbox, "E");
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 10);
+  gtk_container_add (GTK_CONTAINER (test->window), frame);
+  gtk_container_add (GTK_CONTAINER (frame), test->eventbox);
+  gtk_container_add (GTK_CONTAINER (test->eventbox), vbox);
+
+  test->button = gtk_button_new_with_label ("Click me!");
+  gtk_widget_set_name (test->button, "B");
+  gtk_box_pack_start (GTK_BOX (vbox), test->button, FALSE, TRUE, 0);
+
+  test->check = gtk_check_button_new_with_label ("Sensitive?");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), TRUE);
+  g_signal_connect (G_OBJECT (test->check),
+                   "toggled", G_CALLBACK (on_check_toggled), test->button);
+  gtk_widget_set_name (test->check, "C");
+  gtk_box_pack_start (GTK_BOX (vbox), test->check, FALSE, TRUE, 0);
+
+  gtk_widget_show_all (test->window);
+
+  gtk_window_move (GTK_WINDOW (test->window), 0, 0);
+
+  sleep_in_main_loop (0.5);
+}
+
+static void
+sensitivity_teardown (CrossingTest *test,
+                     gconstpointer user_data)
+{
+  stop_events (test);
+  gtk_widget_destroy (test->window);
+
+  if (test->queue != NULL)
+    {
+      g_queue_clear (test->queue);
+      test->queue = NULL;
+    }
+}
+
+void
+start_events (CrossingTest *test)
+{
+  if (!test->events_connected)
+    {
+      g_object_connect (G_OBJECT (test->window),
+                       "signal::destroy", gtk_main_quit, NULL,
+                       "signal::enter-notify-event", on_enter, test,
+                       "signal::leave-notify-event", on_leave, test,
+                       NULL);
+      g_object_connect (G_OBJECT (test->eventbox),
+                       "signal::enter-notify-event", on_enter, test,
+                       "signal::leave-notify-event", on_leave, test,
+                       NULL);
+      g_object_connect (G_OBJECT (test->button),
+                       "signal::enter-notify-event", on_enter, test,
+                       "signal::leave-notify-event", on_leave, test,
+                       NULL);
+      g_object_connect (G_OBJECT (test->check),
+                       "signal::enter-notify-event", on_enter, test,
+                       "signal::leave-notify-event", on_leave, test,
+                       NULL);
+      test->events_connected = TRUE;
+    }
+
+  sleep_in_main_loop (0.5);
+}
+
+void
+stop_events (CrossingTest *test)
+{
+  if (test->events_connected)
+    {
+      g_object_disconnect (G_OBJECT (test->window),
+                          "any_signal", gtk_main_quit, NULL,
+                          "any_signal", on_enter, test,
+                          "any_signal", on_leave, test,
+                          NULL);
+      g_object_disconnect (G_OBJECT (test->eventbox),
+                          "any_signal", on_enter, test,
+                          "any_signal", on_leave, test,
+                          NULL);
+      g_object_disconnect (G_OBJECT (test->button),
+                          "any_signal", on_enter, test,
+                          "any_signal", on_leave, test,
+                          NULL);
+      g_object_disconnect (G_OBJECT (test->check),
+                          "any_signal", G_CALLBACK (on_check_toggled), test->button,
+                          "any_signal", on_enter, test,
+                          "any_signal", on_leave, test,
+                          NULL);
+      test->events_connected = FALSE;
+    }
+}
+
+void
+move_cursor_away (CrossingTest *test)
+{
+  gdk_display_warp_pointer (gtk_widget_get_display (test->window),
+                            gtk_widget_get_screen (test->window),
+                            1000, -1000);
+
+  sleep_in_main_loop (0.5);
+}
+
+void
+check_event (CrossingTest *test,
+            const gchar *name,
+            gboolean entered,
+            gboolean synthesized,
+            GdkCrossingMode mode,
+            GdkNotifyType detail)
+{
+  CrossingEventData *evt;
+
+  g_assert (test->queue != NULL);
+
+  evt = g_queue_pop_head (test->queue);
+
+  g_assert (evt->entered == entered);
+  g_assert (strcmp (evt->name, name) == 0);
+  g_assert (evt->synthesized == synthesized);
+  g_assert (evt->mode == mode);
+
+  if (evt->detail != detail)
+    g_print ("%s %s event, detail %d, expected detail %d\n", 
+             synthesized ? "synthesized" : "native",
+             entered ? "enter" : "leave",
+             evt->detail, detail);
+  g_assert (evt->detail == detail);
+}
+
+/* Verify crossing events when moving into and out of a sensitive widget */
+static void
+cursor_on_sensitive (CrossingTest *test,
+                    gconstpointer user_data)
+{
+  move_cursor_away (test);
+
+  start_events (test);
+
+  set_cursor (test->button);
+
+  check_event (test,
+              "W",
+              TRUE,
+              FALSE,  /* native */
+              GDK_CROSSING_NORMAL,
+              GDK_NOTIFY_NONLINEAR_VIRTUAL);
+
+  check_event (test,
+              "E",
+              TRUE,
+              FALSE,  /* native */
+              GDK_CROSSING_NORMAL,
+              GDK_NOTIFY_NONLINEAR_VIRTUAL);
+
+  check_event (test,
+              "B",
+              TRUE,
+              FALSE,  /* native */
+              GDK_CROSSING_NORMAL,
+              GDK_NOTIFY_NONLINEAR);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  move_cursor_away (test);
+
+  check_event (test,
+              "B",
+              FALSE,
+              FALSE,  /* native */
+              GDK_CROSSING_NORMAL,
+              GDK_NOTIFY_NONLINEAR);
+
+  check_event (test,
+              "E",
+              FALSE,
+              FALSE,  /* native */
+              GDK_CROSSING_NORMAL,
+              GDK_NOTIFY_NONLINEAR_VIRTUAL);
+
+  check_event (test,
+              "W",
+              FALSE,
+              FALSE,  /* native */
+              GDK_CROSSING_NORMAL,
+              GDK_NOTIFY_NONLINEAR_VIRTUAL);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+static void
+change_sensitive_to_insensitive (CrossingTest *test,
+                                gconstpointer user_data)
+{
+  move_cursor_away (test);
+  set_cursor (test->button);
+
+  start_events (test);
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
+
+  check_event (test,
+              "B",
+              FALSE,
+              TRUE,  /* synthesized */
+              GDK_CROSSING_STATE_CHANGED,
+              GDK_NOTIFY_ANCESTOR);
+
+  check_event (test,
+               "E",
+              FALSE,
+              TRUE,  /* synthesized */
+               GDK_CROSSING_STATE_CHANGED,
+               GDK_NOTIFY_VIRTUAL);
+
+  check_event (test,
+               "W",
+              FALSE,
+              TRUE,  /* synthesized */
+               GDK_CROSSING_STATE_CHANGED,
+               GDK_NOTIFY_VIRTUAL);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+static void
+change_insensitive_to_sensitive (CrossingTest *test,
+                                gconstpointer user_data)
+{
+  move_cursor_away (test);
+  set_cursor (test->button);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
+
+  start_events (test);
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), TRUE);
+
+  check_event (test,
+               "W",
+               TRUE,
+               TRUE,  /* synthesized */
+               GDK_CROSSING_STATE_CHANGED,
+               GDK_NOTIFY_VIRTUAL);
+
+  check_event (test,
+               "E",
+               TRUE,
+              TRUE,  /* synthesized */
+               GDK_CROSSING_STATE_CHANGED,
+               GDK_NOTIFY_VIRTUAL);
+
+  check_event (test,
+               "B",
+               TRUE,
+              TRUE,  /* synthesized */
+               GDK_CROSSING_STATE_CHANGED,
+               GDK_NOTIFY_ANCESTOR);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+static void
+cursor_from_insensitive_to_sensitive (CrossingTest *test,
+                                     gconstpointer user_data)
+{
+  set_cursor (test->button);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
+
+  start_events (test);
+
+  set_cursor (test->check);
+
+  check_event (test,
+               "C",
+               TRUE,
+               FALSE,  /* native */
+               GDK_CROSSING_NORMAL,
+               GDK_NOTIFY_NONLINEAR);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+static void
+cursor_from_sensitive_to_insensitive (CrossingTest *test,
+                                     gconstpointer user_data)
+{
+  set_cursor (test->check);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (test->check), FALSE);
+
+  start_events (test);
+
+  set_cursor (test->button);
+
+  check_event (test,
+               "C",
+               FALSE,
+               FALSE,  /* native */
+               GDK_CROSSING_NORMAL,
+               GDK_NOTIFY_NONLINEAR);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+static void
+add_gtk_grab (CrossingTest *test,
+             gconstpointer user_data)
+{
+  set_cursor (test->button);
+
+  start_events (test);
+
+  gtk_grab_add (test->check);
+
+  check_event (test,
+              "B",
+              FALSE,
+              TRUE,   /* synthesized */
+              GDK_CROSSING_GTK_GRAB,
+              GDK_NOTIFY_ANCESTOR);
+
+  check_event (test,
+               "E",
+               FALSE,
+              TRUE,   /* synthesized */
+              GDK_CROSSING_GTK_GRAB,
+              GDK_NOTIFY_ANCESTOR);
+
+  check_event (test,
+               "W",
+               FALSE,
+               TRUE,   /* synthesized */
+               GDK_CROSSING_GTK_GRAB,
+              GDK_NOTIFY_ANCESTOR);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+static void
+remove_gtk_grab (CrossingTest *test,
+                gconstpointer user_data)
+{
+  set_cursor (test->button);
+
+  gtk_grab_add (test->check);
+
+  start_events (test);
+
+  gtk_grab_remove (test->check);
+
+  check_event (test,
+               "B",
+               TRUE,
+               TRUE,   /* synthesized */
+               GDK_CROSSING_GTK_UNGRAB,
+              GDK_NOTIFY_ANCESTOR);
+
+  check_event (test,
+               "E",
+               TRUE,
+               TRUE,   /* synthesized */
+              GDK_CROSSING_GTK_UNGRAB,
+               GDK_NOTIFY_ANCESTOR);
+
+  check_event (test,
+               "W",
+               TRUE,
+               TRUE,   /* synthesized */
+               GDK_CROSSING_GTK_UNGRAB,
+               GDK_NOTIFY_ANCESTOR);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+static void
+cursor_from_shadowed_to_unshadowed (CrossingTest *test,
+                                   gconstpointer user_data)
+{
+  set_cursor (test->button);
+
+  gtk_grab_add (test->check);
+
+  start_events (test);
+
+  set_cursor (test->check);
+
+  check_event (test,
+               "C",
+               FALSE,
+               FALSE,   /* native */
+               GDK_CROSSING_NORMAL,
+               GDK_NOTIFY_NONLINEAR);
+
+  check_event (test,
+               "C",
+               TRUE,
+               FALSE,   /* native */
+               GDK_CROSSING_NORMAL,
+               GDK_NOTIFY_NONLINEAR);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+static void
+cursor_from_unshadowed_to_shadowed (CrossingTest *test,
+                                   gconstpointer user_data)
+{
+  set_cursor (test->check);
+
+  gtk_grab_add (test->check);
+
+  start_events (test);
+
+  set_cursor (test->button);
+
+  check_event (test,
+               "C",
+               FALSE,
+               FALSE,   /* native */
+               GDK_CROSSING_NORMAL,
+               GDK_NOTIFY_NONLINEAR);
+
+  check_event (test,
+               "C",
+               TRUE,
+               FALSE,   /* native */
+               GDK_CROSSING_NORMAL,
+               GDK_NOTIFY_NONLINEAR);
+
+  g_assert (g_queue_is_empty (test->queue));
+
+  stop_events (test);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  gtk_test_init (&argc, &argv, NULL);
+
+  g_test_add ("/crossings/cursor-on-sensitive", CrossingTest, NULL,
+             sensitivity_setup, cursor_on_sensitive, sensitivity_teardown);
+
+  g_test_add ("/crossings/change-sensitive-to-insensitive", CrossingTest, NULL,
+             sensitivity_setup, change_sensitive_to_insensitive, sensitivity_teardown);
+
+  g_test_add ("/crossings/cursor-from-insensitive-to-sensitive", CrossingTest, NULL,
+             sensitivity_setup, cursor_from_insensitive_to_sensitive, sensitivity_teardown);
+
+  g_test_add ("/crossings/cursor-from-sensitive-to-insensitive", CrossingTest, NULL,
+             sensitivity_setup, cursor_from_sensitive_to_insensitive, sensitivity_teardown);
+
+  g_test_add ("/crossings/change-insensitive-to-sensitive", CrossingTest, NULL,
+             sensitivity_setup, change_insensitive_to_sensitive, sensitivity_teardown);
+
+  g_test_add ("/crossings/add-gtk-grab", CrossingTest, NULL,
+             sensitivity_setup, add_gtk_grab, sensitivity_teardown);
+
+  g_test_add ("/crossings/remove-gtk-grab", CrossingTest, NULL,
+             sensitivity_setup, remove_gtk_grab, sensitivity_teardown);
+
+  g_test_add ("/crossings/cursor-from-shadowed-to-unshadowed", CrossingTest, NULL,
+             sensitivity_setup, cursor_from_shadowed_to_unshadowed, sensitivity_teardown);
+
+  g_test_add ("/crossings/cursor-from-unshadowed-to-shadowed", CrossingTest, NULL,
+             sensitivity_setup, cursor_from_unshadowed_to_shadowed, sensitivity_teardown);
+
+  return g_test_run ();
+}
diff --git a/testsuite/gtk/defaultvalue.c b/testsuite/gtk/defaultvalue.c
new file mode 100644 (file)
index 0000000..ce1ad3b
--- /dev/null
@@ -0,0 +1,347 @@
+/* Gtk+ default value tests
+ * Copyright (C) 2007 Christian Persch
+ *               2007 Johan Dahlin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkunixprint.h>
+
+static void
+check_property (const char *output,
+               GParamSpec *pspec,
+               GValue *value)
+{
+  GValue default_value = G_VALUE_INIT;
+  char *v, *dv, *msg;
+
+  if (g_param_value_defaults (pspec, value))
+      return;
+
+  g_value_init (&default_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+  g_param_value_set_default (pspec, &default_value);
+      
+  v = g_strdup_value_contents (value);
+  dv = g_strdup_value_contents (&default_value);
+  
+  msg = g_strdup_printf ("%s %s.%s: %s != %s\n",
+                        output,
+                        g_type_name (pspec->owner_type),
+                        pspec->name,
+                        dv, v);
+  g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__,
+                      G_STRFUNC, msg);
+  g_free (msg);
+  
+  g_free (v);
+  g_free (dv);
+  g_value_unset (&default_value);
+}
+
+static void
+test_type (gconstpointer data)
+{
+  GObjectClass *klass;
+  GObject *instance;
+  GParamSpec **pspecs;
+  guint n_pspecs, i;
+  GType type;
+
+  type = * (GType *) data;
+
+  if (!G_TYPE_IS_CLASSED (type))
+    return;
+
+  if (G_TYPE_IS_ABSTRACT (type))
+    return;
+
+  if (!g_type_is_a (type, G_TYPE_OBJECT))
+    return;
+
+  /* These can't be freely constructed/destroyed */
+  if (g_type_is_a (type, GTK_TYPE_PRINT_JOB) ||
+      g_type_is_a (type, GTK_TYPE_APPLICATION) ||
+      g_type_is_a (type, GDK_TYPE_PIXBUF_LOADER) ||
+      g_type_is_a (type, gdk_pixbuf_simple_anim_iter_get_type ()))
+    return;
+
+  klass = g_type_class_ref (type);
+  
+  if (g_type_is_a (type, GTK_TYPE_SETTINGS))
+    instance = g_object_ref (gtk_settings_get_default ());
+  else if (g_type_is_a (type, GDK_TYPE_WINDOW))
+    {
+      GdkWindowAttr attributes;
+      attributes.window_type = GDK_WINDOW_TEMP;
+      attributes.event_mask = 0;
+      attributes.width = 100;
+      attributes.height = 100;
+      instance = g_object_ref (gdk_window_new (NULL, &attributes, 0));
+    }
+  else
+    instance = g_object_new (type, NULL);
+
+  if (g_type_is_a (type, G_TYPE_INITIALLY_UNOWNED))
+    g_object_ref_sink (instance);
+
+  pspecs = g_object_class_list_properties (klass, &n_pspecs);
+  for (i = 0; i < n_pspecs; ++i)
+    {
+      GParamSpec *pspec = pspecs[i];
+      GValue value = G_VALUE_INIT;
+      
+      if (pspec->owner_type != type)
+       continue;
+
+      if ((pspec->flags & G_PARAM_READABLE) == 0)
+       continue;
+
+      if (g_type_is_a (type, GDK_TYPE_DISPLAY_MANAGER) &&
+         (strcmp (pspec->name, "default-display") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_ABOUT_DIALOG) &&
+         (strcmp (pspec->name, "program-name") == 0))
+       continue;
+      
+      /* These are set to the current date */
+      if (g_type_is_a (type, GTK_TYPE_CALENDAR) &&
+         (strcmp (pspec->name, "year") == 0 ||
+          strcmp (pspec->name, "month") == 0 ||
+          strcmp (pspec->name, "day") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_CELL_RENDERER_TEXT) &&
+         (strcmp (pspec->name, "background-gdk") == 0 ||
+          strcmp (pspec->name, "foreground-gdk") == 0 ||
+          strcmp (pspec->name, "font") == 0 ||
+          strcmp (pspec->name, "font-desc") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_CELL_VIEW) &&
+         (strcmp (pspec->name, "background-gdk") == 0 ||
+          strcmp (pspec->name, "foreground-gdk") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_COLOR_BUTTON) &&
+         strcmp (pspec->name, "color") == 0)
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_COLOR_SELECTION) &&
+         strcmp (pspec->name, "current-color") == 0)
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_COLOR_SELECTION_DIALOG) &&
+         (strcmp (pspec->name, "color-selection") == 0 ||
+          strcmp (pspec->name, "ok-button") == 0 ||
+          strcmp (pspec->name, "help-button") == 0 ||
+          strcmp (pspec->name, "cancel-button") == 0))
+       continue;
+
+      /* Default invisible char is determined at runtime */
+      if (g_type_is_a (type, GTK_TYPE_ENTRY) &&
+         (strcmp (pspec->name, "invisible-char") == 0 ||
+           strcmp (pspec->name, "buffer") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_FONT_SELECTION) &&
+         strcmp (pspec->name, "font") == 0)
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_LAYOUT) &&
+         (strcmp (pspec->name, "hadjustment") == 0 ||
+           strcmp (pspec->name, "vadjustment") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_MESSAGE_DIALOG) &&
+          (strcmp (pspec->name, "image") == 0 ||
+           strcmp (pspec->name, "message-area") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_PANED) &&
+         strcmp (pspec->name, "max-position") == 0)
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_PRINT_OPERATION) &&
+         strcmp (pspec->name, "job-name") == 0)
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_PRINT_UNIX_DIALOG) &&
+         (strcmp (pspec->name, "page-setup") == 0 ||
+          strcmp (pspec->name, "print-settings") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_PROGRESS_BAR) &&
+          strcmp (pspec->name, "adjustment") == 0)
+        continue;
+
+      /* filename value depends on $HOME */
+      if (g_type_is_a (type, GTK_TYPE_RECENT_MANAGER) &&
+          (strcmp (pspec->name, "filename") == 0 ||
+          strcmp (pspec->name, "size") == 0))
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_SCALE_BUTTON) &&
+          strcmp (pspec->name, "adjustment") == 0)
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_SCROLLED_WINDOW) &&
+         (strcmp (pspec->name, "hadjustment") == 0 ||
+           strcmp (pspec->name, "vadjustment") == 0))
+       continue;
+
+      /* these defaults come from XResources */
+      if (g_type_is_a (type, GTK_TYPE_SETTINGS) &&
+          strncmp (pspec->name, "gtk-xft-", 8) == 0)
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_SETTINGS) &&
+          (strcmp (pspec->name, "color-hash") == 0 ||
+          strcmp (pspec->name, "gtk-cursor-theme-name") == 0 ||
+          strcmp (pspec->name, "gtk-cursor-theme-size") == 0 ||
+          strcmp (pspec->name, "gtk-dnd-drag-threshold") == 0 ||
+          strcmp (pspec->name, "gtk-double-click-time") == 0 ||
+          strcmp (pspec->name, "gtk-fallback-icon-theme") == 0 ||
+          strcmp (pspec->name, "gtk-file-chooser-backend") == 0 ||
+          strcmp (pspec->name, "gtk-icon-theme-name") == 0 ||
+          strcmp (pspec->name, "gtk-im-module") == 0 ||
+          strcmp (pspec->name, "gtk-key-theme-name") == 0 ||
+          strcmp (pspec->name, "gtk-theme-name") == 0 ||
+           strcmp (pspec->name, "gtk-sound-theme-name") == 0 ||
+           strcmp (pspec->name, "gtk-enable-input-feedback-sounds") == 0 ||
+           strcmp (pspec->name, "gtk-enable-event-sounds") == 0))
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_SPIN_BUTTON) &&
+          (strcmp (pspec->name, "adjustment") == 0))
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_STATUS_ICON) &&
+          (strcmp (pspec->name, "size") == 0 ||
+           strcmp (pspec->name, "screen") == 0))
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_TEXT_BUFFER) &&
+          (strcmp (pspec->name, "tag-table") == 0 ||
+           strcmp (pspec->name, "copy-target-list") == 0 ||
+           strcmp (pspec->name, "paste-target-list") == 0))
+        continue;
+
+      /* language depends on the current locale */
+      if (g_type_is_a (type, GTK_TYPE_TEXT_TAG) &&
+          (strcmp (pspec->name, "background-gdk") == 0 ||
+           strcmp (pspec->name, "foreground-gdk") == 0 ||
+          strcmp (pspec->name, "language") == 0 ||
+          strcmp (pspec->name, "font") == 0 ||
+          strcmp (pspec->name, "font-desc") == 0))
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_TEXT_VIEW) &&
+          strcmp (pspec->name, "buffer") == 0)
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_TOOL_ITEM_GROUP) &&
+          strcmp (pspec->name, "label-widget") == 0)
+        continue;
+
+      if (g_type_is_a (type, GTK_TYPE_TREE_VIEW) &&
+         (strcmp (pspec->name, "hadjustment") == 0 ||
+           strcmp (pspec->name, "vadjustment") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_VIEWPORT) &&
+         (strcmp (pspec->name, "hadjustment") == 0 ||
+           strcmp (pspec->name, "vadjustment") == 0))
+       continue;
+
+      if (g_type_is_a (type, GTK_TYPE_WIDGET) &&
+         (strcmp (pspec->name, "name") == 0 ||
+          strcmp (pspec->name, "screen") == 0 ||
+          strcmp (pspec->name, "style") == 0))
+       continue;
+
+      /* resize-grip-visible is determined at runtime */
+      if (g_type_is_a (type, GTK_TYPE_WINDOW) &&
+          (strcmp (pspec->name, "resize-grip-visible") == 0))
+        continue;
+
+      if (g_test_verbose ())
+      g_print ("Property %s.%s\n", 
+            g_type_name (pspec->owner_type),
+            pspec->name);
+      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      g_object_get_property (instance, pspec->name, &value);
+      check_property ("Property", pspec, &value);
+      g_value_unset (&value);
+    }
+  g_free (pspecs);
+
+  if (g_type_is_a (type, GTK_TYPE_WIDGET))
+    {
+      pspecs = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (klass), &n_pspecs);
+      
+      for (i = 0; i < n_pspecs; ++i)
+       {
+         GParamSpec *pspec = pspecs[i];
+         GValue value = G_VALUE_INIT;
+         
+         if (pspec->owner_type != type)
+           continue;
+
+         if ((pspec->flags & G_PARAM_READABLE) == 0)
+           continue;
+         
+         g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+         gtk_widget_style_get_property (GTK_WIDGET (instance), pspec->name, &value);
+         check_property ("Style property", pspec, &value);
+         g_value_unset (&value);
+       }
+
+      g_free (pspecs);
+    }
+  
+  if (g_type_is_a (type, GDK_TYPE_WINDOW))
+    gdk_window_destroy (GDK_WINDOW (instance));
+  else
+    g_object_unref (instance);
+  
+  g_type_class_unref (klass);
+}
+
+int
+main (int argc, char **argv)
+{
+  const GType *otypes;
+  guint i;
+
+  gtk_test_init (&argc, &argv);
+  gtk_test_register_all_types();
+  
+  otypes = gtk_test_list_all_types (NULL);
+  for (i = 0; otypes[i]; i++)
+    {
+      gchar *testname;
+      
+      testname = g_strdup_printf ("/Default Values/%s",
+                                 g_type_name (otypes[i]));
+      g_test_add_data_func (testname,
+                            &otypes[i],
+                           test_type);
+      g_free (testname);
+    }
+  
+  return g_test_run();
+}
diff --git a/testsuite/gtk/entry.c b/testsuite/gtk/entry.c
new file mode 100644 (file)
index 0000000..074f5a5
--- /dev/null
@@ -0,0 +1,319 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+static gint serial = 0;
+
+typedef struct {
+  gint serial;
+  gint count;
+  gint start;
+  gint end;
+  gchar *text;
+  gchar *new_text;
+  gint position;
+  gint length;
+} EntryData;
+
+static void
+notify (GtkEditable *editable, GParamSpec *pspec, EntryData *data)
+{
+  data->serial = serial++;
+  data->count++;
+  data->text = gtk_editable_get_chars (editable, 0, -1);
+  gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
+
+#if 0
+  g_print ("notify::%s\n", pspec->name);
+  g_print ("\ttext: %s\n", data->text);
+  g_print ("\tstart: %d\n", data->start);
+  g_print ("\tend: %d\n", data->end);
+#endif
+}
+
+static void
+insert_text (GtkEditable *editable,
+             const gchar *new_text,
+             gint         new_text_length,
+             gint        *position,
+             EntryData   *data)
+{
+  data->serial = serial++;
+  data->count++;
+  data->text = gtk_editable_get_chars (editable, 0, -1);
+  gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
+  data->new_text = g_strdup (new_text);
+  data->position = *position;
+  data->length = new_text_length;
+
+#if 0
+  g_print ("insert-text \"%s\", %d\n", new_text, *position);
+  g_print ("\ttext: %s\n", data->text);
+  g_print ("\tstart: %d\n", data->start);
+  g_print ("\tend: %d\n", data->end);
+#endif
+}
+
+static void
+delete_text (GtkEditable *editable,
+             gint         start_pos,
+             gint         end_pos,
+             EntryData   *data)
+{
+  data->serial = serial++;
+  data->count++;
+  data->text = gtk_editable_get_chars (editable, 0, -1);
+  gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
+  data->position = start_pos;
+  data->length = end_pos - start_pos;
+
+#if 0
+  g_print ("delete-text %d %d\n", start_pos, end_pos);
+  g_print ("\ttext: %s\n", data->text);
+  g_print ("\tstart: %d\n", data->start);
+  g_print ("\tend: %d\n", data->end);
+#endif
+}
+
+static void
+changed (GtkEditable *editable,
+         EntryData   *data)
+{
+  data->serial = serial++;
+  data->count++;
+  data->text = gtk_editable_get_chars (editable, 0, -1);
+  gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
+
+#if 0
+  g_print ("changed\n");
+  g_print ("\ttext: %s\n", data->text);
+  g_print ("\tstart: %d\n", data->start);
+  g_print ("\tend: %d\n", data->end);
+#endif
+}
+
+static void
+test_insert (void)
+{
+  GtkWidget *entry;
+  gint pos;
+  EntryData data1;
+  EntryData data2;
+  EntryData data3;
+  EntryData data4;
+  EntryData data5;
+  EntryData data6;
+
+  entry = gtk_entry_new ();
+  g_object_ref_sink (entry);
+
+  gtk_entry_set_text (GTK_ENTRY (entry), "bar");
+  gtk_editable_set_position (GTK_EDITABLE (entry), -1);
+  pos = gtk_editable_get_position (GTK_EDITABLE (entry));
+  g_assert_cmpint (pos, ==, 3);
+
+  data1.count = 0;
+  data2.count = 0;
+  data3.count = 0;
+  data4.count = 0;
+  data5.count = 0;
+  data6.count = 0;
+  g_signal_connect (entry, "notify::cursor-position",
+                    G_CALLBACK (notify), &data1);
+  g_signal_connect (entry, "notify::selection-bound",
+                    G_CALLBACK (notify), &data2);
+  g_signal_connect (entry, "notify::text",
+                    G_CALLBACK (notify), &data3);
+  g_signal_connect (entry, "insert-text",
+                    G_CALLBACK (insert_text), &data4);
+  g_signal_connect (entry, "delete-text",
+                    G_CALLBACK (delete_text), &data5);
+  g_signal_connect (entry, "changed",
+                    G_CALLBACK (changed), &data6);
+
+  pos = 0;
+  gtk_editable_insert_text (GTK_EDITABLE (entry), "foo", -1, &pos);
+  g_assert_cmpint (pos, ==, 3);
+
+  pos = gtk_editable_get_position (GTK_EDITABLE (entry));
+  g_assert_cmpint (pos, ==, 6);
+
+  /* Check that notification for ::text, ::cursor-position and
+   * ::selection-bound happens in a consistent state after the
+   * change.
+   */
+  g_assert_cmpint (data1.count, ==, 1);
+  g_assert_cmpint (data1.start, ==, 6);
+  g_assert_cmpint (data1.end, ==, 6);
+  g_assert_cmpstr (data1.text, ==, "foobar");
+  g_free (data1.text);
+
+  g_assert_cmpint (data2.count, ==, 1);
+  g_assert_cmpint (data2.start, ==, 6);
+  g_assert_cmpint (data2.end, ==, 6);
+  g_assert_cmpstr (data2.text, ==, "foobar");
+  g_free (data2.text);
+
+  g_assert_cmpint (data3.count, ==, 1);
+  g_assert_cmpint (data3.start, ==, 6);
+  g_assert_cmpint (data3.end, ==, 6);
+  g_assert_cmpstr (data3.text, ==, "foobar");
+  g_free (data3.text);
+
+  /* Check that ::insert-text sees the state _before_ the insertion */
+  g_assert_cmpint (data4.count, ==, 1);
+  g_assert_cmpint (data4.start, ==, 3);
+  g_assert_cmpint (data4.end, ==, 3);
+  g_assert_cmpstr (data4.text, ==, "bar");
+  g_assert_cmpint (data4.position, ==, 0);
+  g_assert_cmpint (data4.length, ==, 3);
+  g_assert_cmpstr (data4.new_text, ==, "foo");
+  g_free (data4.text);
+  g_free (data4.new_text);
+
+  /* no deletion here */
+  g_assert_cmpint (data5.count, ==, 0);
+
+  /* Check that ::changed sees the post-change state */
+  g_assert_cmpint (data6.count, ==, 1);
+  g_assert_cmpint (data6.start, ==, 6);
+  g_assert_cmpint (data6.end, ==, 6);
+  g_assert_cmpstr (data6.text, ==, "foobar");
+  g_free (data6.text);
+
+  /* Now check ordering: ::insert-text comes before ::notify */
+  g_assert_cmpint (data4.serial, <, data1.serial);
+  g_assert_cmpint (data4.serial, <, data2.serial);
+  g_assert_cmpint (data4.serial, <, data3.serial);
+
+  /* ... and ::changed comes after ::notify */
+  g_assert_cmpint (data6.serial, >, data1.serial);
+  g_assert_cmpint (data6.serial, >, data2.serial);
+  g_assert_cmpint (data6.serial, >, data3.serial);
+
+  g_object_unref (entry);
+}
+
+static void
+test_delete (void)
+{
+  GtkWidget *entry;
+  gint pos;
+  EntryData data1;
+  EntryData data2;
+  EntryData data3;
+  EntryData data4;
+  EntryData data5;
+  EntryData data6;
+
+  entry = gtk_entry_new ();
+  g_object_ref_sink (entry);
+
+  gtk_entry_set_text (GTK_ENTRY (entry), "foobar");
+  gtk_editable_set_position (GTK_EDITABLE (entry), -1);
+  pos = gtk_editable_get_position (GTK_EDITABLE (entry));
+  g_assert_cmpint (pos, ==, 6);
+
+  data1.count = 0;
+  data2.count = 0;
+  data3.count = 0;
+  data4.count = 0;
+  data5.count = 0;
+  data6.count = 0;
+  g_signal_connect (entry, "notify::cursor-position",
+                    G_CALLBACK (notify), &data1);
+  g_signal_connect (entry, "notify::selection-bound",
+                    G_CALLBACK (notify), &data2);
+  g_signal_connect (entry, "notify::text",
+                    G_CALLBACK (notify), &data3);
+  g_signal_connect (entry, "insert-text",
+                    G_CALLBACK (insert_text), &data4);
+  g_signal_connect (entry, "delete-text",
+                    G_CALLBACK (delete_text), &data5);
+  g_signal_connect (entry, "changed",
+                    G_CALLBACK (changed), &data6);
+
+  gtk_editable_delete_text (GTK_EDITABLE (entry), 0, 3);
+
+  pos = gtk_editable_get_position (GTK_EDITABLE (entry));
+  g_assert_cmpint (pos, ==, 3);
+
+  /* Check that notification for ::text, ::cursor-position and
+   * ::selection-bound happens in a consistent state after the
+   * change.
+   */
+  g_assert_cmpint (data1.count, ==, 1);
+  g_assert_cmpint (data1.start, ==, 3);
+  g_assert_cmpint (data1.end, ==, 3);
+  g_assert_cmpstr (data1.text, ==, "bar");
+  g_free (data1.text);
+
+  g_assert_cmpint (data2.count, ==, 1);
+  g_assert_cmpint (data2.start, ==, 3);
+  g_assert_cmpint (data2.end, ==, 3);
+  g_assert_cmpstr (data2.text, ==, "bar");
+  g_free (data2.text);
+
+  g_assert_cmpint (data3.count, ==, 1);
+  g_assert_cmpint (data3.start, ==, 3);
+  g_assert_cmpint (data3.end, ==, 3);
+  g_assert_cmpstr (data3.text, ==, "bar");
+  g_free (data3.text);
+
+  /* no insertion here */
+  g_assert_cmpint (data4.count, ==, 0);
+
+  /* Check that ::delete-text sees the state _before_ the insertion */
+  g_assert_cmpint (data5.count, ==, 1);
+  g_assert_cmpint (data5.start, ==, 6);
+  g_assert_cmpint (data5.end, ==, 6);
+  g_assert_cmpstr (data5.text, ==, "foobar");
+  g_assert_cmpint (data5.position, ==, 0);
+  g_assert_cmpint (data5.length, ==, 3);
+  g_free (data5.text);
+
+  /* Check that ::changed sees the post-change state */
+  g_assert_cmpint (data6.count, ==, 1);
+  g_assert_cmpint (data6.start, ==, 3);
+  g_assert_cmpint (data6.end, ==, 3);
+  g_assert_cmpstr (data6.text, ==, "bar");
+  g_free (data6.text);
+
+  /* Now check ordering: ::delete-text comes before ::notify */
+  g_assert_cmpint (data5.serial, <, data1.serial);
+  g_assert_cmpint (data5.serial, <, data2.serial);
+  g_assert_cmpint (data5.serial, <, data3.serial);
+
+  /* ... and ::changed comes after ::notify */
+  g_assert_cmpint (data6.serial, >, data1.serial);
+  g_assert_cmpint (data6.serial, >, data2.serial);
+  g_assert_cmpint (data6.serial, >, data3.serial);
+  g_object_unref (entry);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  gtk_test_init (&argc, &argv);
+
+  g_test_add_func ("/entry/delete", test_delete);
+  g_test_add_func ("/entry/insert", test_insert);
+
+  return g_test_run();
+}
diff --git a/testsuite/gtk/expander.c b/testsuite/gtk/expander.c
new file mode 100644 (file)
index 0000000..87b915f
--- /dev/null
@@ -0,0 +1,92 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2001.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+#include <gtk/gtk.h>
+
+static void
+test_click_expander (void)
+{
+  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test click on expander");
+  GtkWidget *expander = gtk_expander_new ("Test Expander");
+  GtkWidget *label = gtk_label_new ("Test Label");
+  gboolean expanded;
+  gboolean simsuccess;
+  gtk_container_add (GTK_CONTAINER (expander), label);
+  gtk_container_add (GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (window))), expander);
+  gtk_widget_show (expander);
+  gtk_widget_show (label);
+  gtk_widget_show_now (window);
+  /* check initial expander state */
+  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
+  g_assert (!expanded);
+  /* check expanding */
+  simsuccess = gtk_test_widget_click (expander, 1, 0);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
+    gtk_main_iteration ();
+  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
+  g_assert (expanded);
+  /* check collapsing */
+  simsuccess = gtk_test_widget_click (expander, 1, 0);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
+    gtk_main_iteration ();
+  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
+  g_assert (!expanded);
+}
+
+static void
+test_click_content_widget (void)
+{
+  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test click on content widget");
+  GtkWidget *expander = gtk_expander_new ("Test Expander");
+  GtkWidget *entry = gtk_entry_new ();
+  gboolean expanded;
+  gboolean simsuccess;
+  gtk_container_add (GTK_CONTAINER (expander), entry);
+  gtk_container_add (GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (window))), expander);
+  gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
+  gtk_widget_show (expander);
+  gtk_widget_show (entry);
+  gtk_widget_show_now (window);
+
+  /* check click on content with expander open */
+  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
+  g_assert (expanded);
+  simsuccess = gtk_test_widget_click (entry, 1, 0);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ()) /* let expander timeout/idle handlers update */
+    gtk_main_iteration ();
+  expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander));
+  g_assert (expanded);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  gtk_test_init (&argc, &argv);
+  g_test_add_func ("/expander/click-expander", test_click_expander);
+  g_test_add_func ("/expander/click-content-widget", test_click_content_widget);
+  return g_test_run();
+}
diff --git a/testsuite/gtk/file-chooser-test-dir/empty b/testsuite/gtk/file-chooser-test-dir/empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/gtk/file-chooser-test-dir/text.txt b/testsuite/gtk/file-chooser-test-dir/text.txt
new file mode 100644 (file)
index 0000000..cd08755
--- /dev/null
@@ -0,0 +1 @@
+Hello world!
diff --git a/testsuite/gtk/filechooser.c b/testsuite/gtk/filechooser.c
new file mode 100644 (file)
index 0000000..529f87d
--- /dev/null
@@ -0,0 +1,2492 @@
+/* GTK - The GIMP Toolkit
+ * autotestfilechooser.c: Automated unit tests for the GtkFileChooser widget
+ * Copyright (C) 2005, Novell, Inc.
+ *
+ * Authors:
+ *   Federico Mena-Quintero <federico@novell.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* TODO:
+ *
+ * - In test_reload_sequence(), test that the selection is preserved properly
+ *   between unmap/map.
+ *
+ * - More tests!
+ */
+
+#define SLEEP_DURATION  100
+
+#include "config.h"
+#include <string.h>
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+#include "gtk/gtkfilechooserdefault.h"
+#include "gtk/gtkfilechooserentry.h"
+
+#if 0
+static const char *
+get_action_name (GtkFileChooserAction action)
+{
+  switch (action)
+    {
+    case GTK_FILE_CHOOSER_ACTION_OPEN:          return "OPEN";
+    case GTK_FILE_CHOOSER_ACTION_SAVE:          return "SAVE";
+    case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: return "SELECT_FOLDER";
+    case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER: return "CREATE_FOLDER";
+
+    default:
+      g_assert_not_reached ();
+      return NULL;
+    }
+}
+#endif
+
+#ifdef BROKEN_TESTS
+static void
+log_test (gboolean passed, const char *test_name, ...)
+{
+  va_list args;
+  char *str;
+
+  va_start (args, test_name);
+  str = g_strdup_vprintf (test_name, args);
+  va_end (args);
+
+  if (g_test_verbose())
+    g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str);
+  g_free (str);
+}
+
+typedef void (* SetFilenameFn) (GtkFileChooser *chooser, gpointer data);
+typedef void (* CompareFilenameFn) (GtkFileChooser *chooser, gpointer data);
+
+struct test_set_filename_closure {
+  GtkWidget *chooser;
+  GtkWidget *accept_button;
+  gboolean focus_button;
+};
+
+static gboolean
+set_filename_timeout_cb (gpointer data)
+{
+  struct test_set_filename_closure *closure;
+
+  closure = data;
+
+  if (closure->focus_button)
+    gtk_widget_grab_focus (closure->accept_button);
+
+  gtk_button_clicked (GTK_BUTTON (closure->accept_button));
+
+  return FALSE;
+}
+#endif
+
+
+static guint wait_for_idle_id = 0;
+
+static gboolean
+wait_for_idle_idle (gpointer data)
+{
+  wait_for_idle_id = 0;
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+wait_for_idle (void)
+{
+  wait_for_idle_id = g_idle_add_full (G_PRIORITY_LOW + 100,
+                                     wait_for_idle_idle,
+                                     NULL, NULL);
+
+  while (wait_for_idle_id)
+    gtk_main_iteration ();
+}
+
+#ifdef BROKEN_TESTS
+static void
+test_set_filename (GtkFileChooserAction action,
+                  gboolean focus_button,
+                  SetFilenameFn set_filename_fn,const
+                  CompareFilenameFn compare_filename_fn,
+                  gpointer data)
+{
+  GtkWidget *chooser;
+  struct test_set_filename_closure closure;
+  guint timeout_id;
+
+  chooser = gtk_file_chooser_dialog_new ("hello", NULL, action,
+                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                        NULL);
+
+  closure.chooser = chooser;
+  closure.accept_button = gtk_dialog_add_button (GTK_DIALOG (chooser), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
+  closure.focus_button = focus_button;
+
+  gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
+
+  (* set_filename_fn) (GTK_FILE_CHOOSER (chooser), data);
+
+  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, set_filename_timeout_cb, &closure, NULL);
+  gtk_dialog_run (GTK_DIALOG (chooser));
+  g_source_remove (timeout_id);
+
+  (* compare_filename_fn) (GTK_FILE_CHOOSER (chooser), data);
+
+  gtk_widget_destroy (chooser);
+}
+
+static void
+set_filename_cb (GtkFileChooser *chooser, gpointer data)
+{
+  const char *filename;
+
+  filename = data;
+  gtk_file_chooser_set_filename (chooser, filename);
+}
+
+static void
+compare_filename_cb (GtkFileChooser *chooser, gpointer data)
+{
+  const char *filename;
+  char *out_filename;
+
+  filename = data;
+  out_filename = gtk_file_chooser_get_filename (chooser);
+
+  g_assert_cmpstr (out_filename, ==, filename);
+
+  if (out_filename)
+    g_free (out_filename);
+}
+
+typedef struct
+{
+  const char *test_name;
+  GtkFileChooserAction action;
+  const char *filename;
+  gboolean focus_button;
+} TestSetFilenameSetup;
+
+static void
+test_black_box_set_filename (gconstpointer data)
+{
+  const TestSetFilenameSetup *setup = data;
+
+  test_set_filename (setup->action, setup->focus_button, set_filename_cb, compare_filename_cb, (char *) setup->filename);
+}
+
+struct current_name_closure {
+       const char *path;
+       const char *current_name;
+};
+
+static void
+set_current_name_cb (GtkFileChooser *chooser, gpointer data)
+{
+  struct current_name_closure *closure;
+
+  closure = data;
+
+  gtk_file_chooser_set_current_folder (chooser, closure->path);
+  gtk_file_chooser_set_current_name (chooser, closure->current_name);
+}
+
+static void
+compare_current_name_cb (GtkFileChooser *chooser, gpointer data)
+{
+  struct current_name_closure *closure;
+  char *out_filename;
+  char *filename;
+
+  closure = data;
+
+  out_filename = gtk_file_chooser_get_filename (chooser);
+
+  g_assert (out_filename != NULL);
+
+  filename = g_build_filename (closure->path, closure->current_name, NULL);
+  g_assert_cmpstr (filename, ==, out_filename);
+
+  g_free (filename);
+  g_free (out_filename);
+}
+
+typedef struct
+{
+  const char *test_name;
+  GtkFileChooserAction action;
+  const char *current_name;
+  gboolean focus_button;
+} TestSetCurrentNameSetup;
+
+static void
+test_black_box_set_current_name (gconstpointer data)
+{
+  const TestSetCurrentNameSetup *setup = data;
+  struct current_name_closure closure;
+  char *cwd;
+
+  cwd = g_get_current_dir ();
+
+  closure.path = cwd;
+  closure.current_name = setup->current_name;
+
+  test_set_filename (setup->action, setup->focus_button, set_current_name_cb, compare_current_name_cb, &closure);
+
+  g_free (cwd);
+}
+#endif
+
+/* FIXME: fails in CREATE_FOLDER mode when FOLDER_NAME == "/" */
+
+#if 0
+#define FILE_NAME "/nonexistent"
+#define FILE_NAME_2 "/nonexistent2"
+#define FOLDER_NAME "/etc"
+#define FOLDER_NAME_2 "/usr"
+#else
+#define FILE_NAME "/etc/passwd"
+#define FILE_NAME_2 "/etc/group"
+#define FOLDER_NAME "/etc"
+#define FOLDER_NAME_2 "/usr"
+#endif
+
+#define CURRENT_NAME "parangaricutirimicuaro.txt"
+#define CURRENT_NAME_FOLDER "parangaricutirimicuaro"
+
+/* https://bugzilla.novell.com/show_bug.cgi?id=184875
+ * http://bugzilla.gnome.org/show_bug.cgi?id=347066
+ * http://bugzilla.gnome.org/show_bug.cgi?id=346058
+ */
+
+#ifdef BROKEN_TESTS
+static void
+setup_set_filename_tests (void)
+{
+  static TestSetFilenameSetup tests[] =
+    {
+      { "/GtkFileChooser/black_box/set_filename/open/no_focus",                 GTK_FILE_CHOOSER_ACTION_OPEN,          FILE_NAME,  FALSE },
+      { "/GtkFileChooser/black_box/set_filename/open/focus",            GTK_FILE_CHOOSER_ACTION_OPEN,          FILE_NAME,  TRUE  },
+      { "/GtkFileChooser/black_box/set_filename/save/no_focus",                 GTK_FILE_CHOOSER_ACTION_SAVE,          FILE_NAME,  FALSE },
+      { "/GtkFileChooser/black_box/set_filename/save/focus",            GTK_FILE_CHOOSER_ACTION_SAVE,          FILE_NAME,  TRUE  },
+      { "/GtkFileChooser/black_box/set_filename/select_folder/no_focus", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,        FOLDER_NAME,FALSE },
+      { "/GtkFileChooser/black_box/set_filename/select_folder/focus",   GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, FOLDER_NAME,TRUE  },
+      { "/GtkFileChooser/black_box/set_filename/create_folder/no_focus", GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,        FOLDER_NAME,FALSE },
+      { "/GtkFileChooser/black_box/set_filename/create_folder/focus",   GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, FOLDER_NAME,TRUE  },
+    };
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    g_test_add_data_func (tests[i].test_name, &tests[i], test_black_box_set_filename);
+}
+
+static void
+setup_set_current_name_tests (void)
+{
+  static TestSetCurrentNameSetup tests[] =
+    {
+      { "/GtkFileChooser/black_box/set_current_name/save/no_focus",         GTK_FILE_CHOOSER_ACTION_SAVE,          CURRENT_NAME,        FALSE },
+      { "/GtkFileChooser/black_box/set_current_name/save/focus",            GTK_FILE_CHOOSER_ACTION_SAVE,          CURRENT_NAME,        TRUE  },
+      { "/GtkFileChooser/black_box/set_current_name/create_folder/no_focus", GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, CURRENT_NAME_FOLDER, FALSE },
+      { "/GtkFileChooser/black_box/set_current_name/create_folder/focus",    GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER, CURRENT_NAME_FOLDER, TRUE  },
+    };
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (tests); i++)
+    g_test_add_data_func (tests[i].test_name, &tests[i], test_black_box_set_current_name);
+}
+#endif
+
+typedef struct
+{
+  const char *shortname;
+  GtkFileChooserAction action;
+  const char *initial_current_folder;
+  const char *initial_filename;
+  gboolean open_dialog;
+  enum {
+    BUTTON,
+    DIALOG
+  } what_to_tweak;
+  const char *tweak_current_folder;
+  const char *tweak_filename;
+  gint dialog_response;
+  gboolean unselect_all;
+  const char *final_current_folder;
+  const char *final_filename;
+} FileChooserButtonTest;
+
+static char *
+make_button_test_name (FileChooserButtonTest *t)
+{
+  return g_strdup_printf ("/GtkFileChooserButton/%s", t->shortname);
+#if 0
+  GString *s = g_string_new ("/GtkFileChooserButton");
+
+  g_string_append_printf (s, "/%s/%s/%s/%s",
+                         get_action_name (t->action),
+                         t->initial_current_folder ? "set_initial_folder" : "no_default_folder",
+                         t->initial_filename ? "set_initial_filename" : "no_initial_filename",
+                         t->open_dialog ? "open_dialog" : "no_dialog");
+
+  if (t->tweak_current_folder)
+    g_string_append (s, "/tweak_current_folder");
+
+  if (t->tweak_filename)
+    g_string_append (s, "/tweak_filename");
+
+  if (t->open_dialog)
+    g_string_append_printf (s, "/%s",
+                           t->dialog_response == GTK_RESPONSE_ACCEPT ? "accept" : "cancel");
+
+  if (t->final_current_folder)
+    g_string_append (s, "/final_current_folder");
+
+  if (t->final_filename)
+    g_string_append (s, "/final_filename");
+
+  return g_string_free (s, FALSE);
+#endif
+}
+
+static gboolean
+sleep_timeout_cb (gpointer data)
+{
+  gtk_main_quit ();
+  return FALSE;
+}
+
+static void
+sleep_in_main_loop (void)
+{
+  guint timeout_id;
+
+  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, 250, sleep_timeout_cb, NULL, NULL);
+  gtk_main ();
+  g_source_remove (timeout_id);
+}
+
+static void
+build_children_list (GtkWidget *widget, gpointer data)
+{
+  GList **list;
+
+  list = data;
+  *list = g_list_prepend (*list, widget);
+}
+
+static GtkWidget *
+find_child_widget_with_atk_role (GtkWidget *widget, AtkRole role)
+{
+  AtkObject *accessible;
+  AtkRole a_role;
+
+  accessible = gtk_widget_get_accessible (widget);
+  a_role = atk_object_get_role (accessible);
+
+  if (a_role == role)
+    return widget;
+  else
+    {
+      GtkWidget *found_child;
+
+      found_child = NULL;
+
+      if (GTK_IS_CONTAINER (widget))
+       {
+         GList *children;
+         GList *l;
+
+         children = NULL;
+         gtk_container_forall (GTK_CONTAINER (widget), build_children_list, &children);
+
+         l = children;
+
+         while (l && !found_child)
+           {
+             GtkWidget *child;
+
+             child = GTK_WIDGET (l->data);
+
+             found_child = find_child_widget_with_atk_role (child, role);
+
+             l = l->next;
+           }
+
+         g_list_free (children);
+       }
+
+      return found_child;
+    }
+}
+
+static const char *
+get_atk_name_for_filechooser_button (GtkFileChooserButton *button)
+{
+  GtkFileChooserAction action;
+  GtkWidget *widget;
+  AtkObject *accessible;
+
+  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button));
+  g_assert (action == GTK_FILE_CHOOSER_ACTION_OPEN || action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+
+  if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
+    widget = find_child_widget_with_atk_role (GTK_WIDGET (button), ATK_ROLE_PUSH_BUTTON);
+  else
+    widget = find_child_widget_with_atk_role (GTK_WIDGET (button), ATK_ROLE_COMBO_BOX);
+
+  accessible = gtk_widget_get_accessible (widget);
+  return atk_object_get_name (accessible);
+}
+
+static void
+check_that_basename_is_shown (GtkFileChooserButton *button, const char *expected_filename)
+{
+  GtkFileChooserAction action;
+  const char *name_on_button;
+  char *expected_basename;
+
+  name_on_button = get_atk_name_for_filechooser_button (button);
+
+  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button));
+  g_assert (action == GTK_FILE_CHOOSER_ACTION_OPEN || action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+
+  if (expected_filename)
+    expected_basename = g_path_get_basename (expected_filename);
+  else
+    expected_basename = NULL;
+
+  if (expected_basename)
+    g_assert_cmpstr (expected_basename, ==, name_on_button);
+  else
+    g_assert_cmpstr (name_on_button, ==, "(None)"); /* see gtkfilechooserbutton.c:FALLBACK_DISPLAY_NAME */ /* FIXME: how do we translate this? */
+
+  g_free (expected_basename);
+}
+
+static const char *
+get_expected_shown_filename (GtkFileChooserAction action, const char *folder_name, const char *filename)
+{
+  if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+    {
+      if (filename)
+       return filename;
+      else
+       return folder_name;
+    }
+  else
+    return filename;
+}
+
+static GtkWidget *
+get_file_chooser_dialog_from_button (GtkFileChooserButton *button)
+{
+  GtkWidget *fc_dialog;
+
+  /* Give me the internal dialog, damnit */
+  fc_dialog = g_object_get_qdata (G_OBJECT (button), g_quark_from_static_string ("gtk-file-chooser-delegate"));
+  g_assert (GTK_IS_FILE_CHOOSER (fc_dialog));
+  g_assert (GTK_IS_DIALOG (fc_dialog));
+
+  return fc_dialog;
+}
+
+typedef struct {
+  GtkWidget *window;
+  GtkWidget *fc_button;
+} WindowAndButton;
+
+static WindowAndButton
+create_window_and_file_chooser_button (GtkFileChooserAction action)
+{
+  WindowAndButton w;
+
+  w.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  w.fc_button = gtk_file_chooser_button_new (action == GTK_FILE_CHOOSER_ACTION_OPEN ? "Select a file" : "Select a folder",
+                                            action);
+  gtk_container_add (GTK_CONTAINER (w.window), w.fc_button);
+
+  return w;
+}
+
+typedef struct
+{
+  GObject *object;
+  GHashTable *signals;
+  gboolean in_main_loop;
+} SignalWatcher;
+
+typedef struct
+{
+  SignalWatcher *watcher;
+  char *signal_name;
+  gulong id;
+  gboolean emitted;
+} SignalConnection;
+
+static SignalWatcher *
+signal_watcher_new (GObject *object)
+{
+  SignalWatcher *watcher = g_new0 (SignalWatcher, 1);
+
+  watcher->object = g_object_ref (object);
+  watcher->signals = g_hash_table_new (g_str_hash, g_str_equal);
+
+  return watcher;
+}
+
+static void
+dummy_callback (GObject *object)
+{
+  /* nothing */
+}
+
+static void
+marshal_notify_cb (gpointer data, GClosure *closure)
+{
+  if (data)
+    {
+      SignalConnection *conn;
+
+      conn = data;
+      conn->emitted = TRUE;
+
+      if (conn->watcher->in_main_loop)
+       {
+         gtk_main_quit ();
+         conn->watcher->in_main_loop = FALSE;
+       }
+    }
+}
+
+static void
+signal_watcher_watch_signal (SignalWatcher *watcher, const char *signal_name)
+{
+  SignalConnection *conn;
+
+  conn = g_hash_table_lookup (watcher->signals, signal_name);
+  if (!conn)
+    {
+      GClosure *closure;
+
+      conn = g_new0 (SignalConnection, 1);
+      conn->watcher = watcher;
+      conn->signal_name = g_strdup (signal_name);
+
+      closure = g_cclosure_new (G_CALLBACK (dummy_callback), NULL, NULL);
+      g_closure_add_marshal_guards (closure, conn, marshal_notify_cb, NULL, marshal_notify_cb);
+      conn->id = g_signal_connect_closure (watcher->object, signal_name, closure, FALSE);
+      conn->emitted = FALSE;
+
+      g_hash_table_insert (watcher->signals, conn->signal_name, conn);
+    }
+  else
+    conn->emitted = FALSE;
+}
+
+static gboolean
+signal_watcher_expect (SignalWatcher *watcher, const char *signal_name, char *unused_description)
+{
+  SignalConnection *conn;
+  gboolean emitted;
+
+  conn = g_hash_table_lookup (watcher->signals, signal_name);
+  g_assert (conn != NULL);
+
+  if (!conn->emitted)
+    {
+      guint timeout_id;
+      
+      timeout_id = gdk_threads_add_timeout_full (G_MAXINT, 1000, sleep_timeout_cb, NULL, NULL);
+
+      watcher->in_main_loop = TRUE;
+      gtk_main ();
+      watcher->in_main_loop = FALSE;
+
+      g_source_remove (timeout_id);
+    }
+
+  emitted = conn->emitted;
+  conn->emitted = FALSE;
+
+  return emitted;
+}
+
+static void
+destroy_connection (gpointer key, gpointer value, gpointer user_data)
+{
+  SignalConnection *conn;
+
+  conn = value;
+  g_signal_handler_disconnect (conn->watcher->object, conn->id);
+  g_free (conn->signal_name);
+  g_free (conn);
+}
+
+static void
+signal_watcher_destroy (SignalWatcher *watcher)
+{
+  g_hash_table_foreach (watcher->signals, destroy_connection, NULL);
+  g_hash_table_destroy (watcher->signals);
+  g_object_unref (watcher->object);
+  g_free (watcher);
+}
+
+static void
+test_file_chooser_button_with_response (const FileChooserButtonTest *setup, gint dialog_response)
+{
+  WindowAndButton w;
+  SignalWatcher *watcher;
+  GtkWidget *fc_dialog = NULL;
+  int iterations;
+  int i;
+
+  w = create_window_and_file_chooser_button (setup->action);
+
+  watcher = signal_watcher_new (G_OBJECT (w.fc_button));
+  signal_watcher_watch_signal (watcher, "current-folder-changed");
+  signal_watcher_watch_signal (watcher, "selection-changed");
+
+  if (setup->initial_current_folder)
+    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w.fc_button), setup->initial_current_folder);
+
+  if (setup->initial_filename)
+    gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (w.fc_button), setup->initial_filename);
+
+  gtk_widget_show_all (w.window);
+  wait_for_idle ();
+
+  if (setup->initial_current_folder)
+    g_assert (signal_watcher_expect (watcher, "current-folder-changed", "initial current folder"));
+
+  if (setup->initial_filename)
+    g_assert (signal_watcher_expect (watcher, "selection-changed", "initial filename"));
+
+  check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button),
+                               get_expected_shown_filename (setup->action, setup->initial_current_folder, setup->initial_filename));
+
+  /* If there is a dialog to be opened, we actually test going through it a
+   * couple of times.  This ensures that any state that the button frobs for
+   * each appearance of the dialog will make sense.
+   */
+  if (setup->open_dialog)
+    iterations = 2;
+  else
+    iterations = 1;
+
+  for (i = 0; i < iterations; i++)
+    {
+      GtkFileChooser *chooser_to_tweak;
+
+      if (setup->open_dialog)
+       {
+         GList *children;
+
+         /* Hack our way into the file chooser button; get its GtkButton child and click it */
+         children = gtk_container_get_children (GTK_CONTAINER (w.fc_button));
+         g_assert (children && GTK_IS_BUTTON (children->data));
+         gtk_button_clicked (GTK_BUTTON (children->data));
+         g_list_free (children);
+
+         wait_for_idle ();
+
+         fc_dialog = get_file_chooser_dialog_from_button (GTK_FILE_CHOOSER_BUTTON (w.fc_button));
+       }
+
+      if (setup->what_to_tweak == BUTTON)
+       chooser_to_tweak = GTK_FILE_CHOOSER (w.fc_button);
+      else if (setup->what_to_tweak == DIALOG)
+       chooser_to_tweak = GTK_FILE_CHOOSER (fc_dialog);
+      else
+       g_assert_not_reached ();
+
+      /* Okay, now frob the button or its optional dialog */
+
+      if (setup->tweak_current_folder)
+       {
+         if (setup->what_to_tweak == BUTTON)
+           signal_watcher_watch_signal (watcher, "current-folder-changed");
+
+         gtk_file_chooser_set_current_folder (chooser_to_tweak, setup->tweak_current_folder);
+
+         if (setup->what_to_tweak == BUTTON)
+           g_assert (signal_watcher_expect (watcher, "current-folder-changed", "tweak current folder in button"));
+       }
+
+      if (setup->tweak_filename)
+       {
+         if (setup->what_to_tweak == BUTTON)
+           signal_watcher_watch_signal (watcher, "selection-changed");
+
+         gtk_file_chooser_select_filename (chooser_to_tweak, setup->tweak_filename);
+
+         if (setup->what_to_tweak == BUTTON)
+           g_assert (signal_watcher_expect (watcher, "selection-changed", "tweak filename in button"));
+       }
+
+      if (setup->unselect_all)
+       {
+         if (setup->what_to_tweak == BUTTON)
+           signal_watcher_watch_signal (watcher, "selection-changed");
+
+         gtk_file_chooser_unselect_all (chooser_to_tweak);
+
+         if (setup->what_to_tweak == BUTTON)
+           g_assert (signal_watcher_expect (watcher, "selection-changed", "tweak unselect_all in button"));
+       }
+
+      wait_for_idle ();
+
+      if (setup->open_dialog)
+       {
+         gtk_dialog_response (GTK_DIALOG (fc_dialog), dialog_response);
+         wait_for_idle ();
+
+         gtk_window_resize (GTK_WINDOW (fc_dialog), 500, 500);
+       }
+
+      if (setup->final_current_folder)
+       {
+         char *folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (w.fc_button));
+
+         g_assert_cmpstr (folder, ==, setup->final_current_folder);
+         g_free (folder);
+       }
+
+      if (setup->final_filename)
+       {
+         char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (w.fc_button));
+
+         g_assert_cmpstr (filename, ==, setup->final_filename);
+         g_free (filename);
+       }
+
+      check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button),
+                                   get_expected_shown_filename (setup->action, setup->final_current_folder, setup->final_filename));
+    }
+
+  signal_watcher_destroy (watcher);
+  gtk_widget_destroy (w.window);
+}
+
+static void
+test_file_chooser_button (gconstpointer data)
+{
+  const FileChooserButtonTest *setup = data;
+
+  test_file_chooser_button_with_response (setup, setup->dialog_response);
+
+  if (setup->open_dialog && setup->dialog_response == GTK_RESPONSE_CANCEL)
+    {
+      /* Runs the test again, with DELETE_EVENT (as if the user closed the
+       * dialog instead of using the Cancel button), since the button misbehaved
+       * in that case sometimes.
+       */
+      test_file_chooser_button_with_response (setup, GTK_RESPONSE_DELETE_EVENT);
+    }
+}
+
+static int
+find_accessible_action_num (AtkObject *object, const char *action_name)
+{
+  AtkAction *action_a;
+  int num_actions;
+  int i;
+
+  action_a = ATK_ACTION (object);
+
+  num_actions = atk_action_get_n_actions (action_a);
+
+  for (i = 0; i < num_actions; i++)
+    if (strcmp (atk_action_get_name (action_a, i), action_name) == 0)
+      return i;
+
+  return -1;
+}
+
+static void
+do_accessible_action (AtkObject *object, const char *action_name)
+{
+  int action_num;
+
+  action_num = find_accessible_action_num (object, action_name);
+  g_assert (action_num != -1);
+
+  atk_action_do_action (ATK_ACTION (object), action_num);
+}
+
+static void
+test_file_chooser_button_combo_box_1 (void)
+{
+  WindowAndButton w;
+  GtkWidget *combo_box;
+  AtkObject *combo_box_a;
+  AtkObject *menu_a;
+  int num_items;
+  int other_index;
+  AtkObject *item_a;
+  GtkWidget *fc_dialog;
+
+  w = create_window_and_file_chooser_button (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+
+  gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (w.fc_button), FOLDER_NAME);
+
+  gtk_widget_show_all (w.window);
+
+  /* Get the accessible for the combo box */
+
+  combo_box = find_child_widget_with_atk_role (GTK_WIDGET (w.fc_button), ATK_ROLE_COMBO_BOX);
+  combo_box_a = gtk_widget_get_accessible (combo_box);
+
+  /* Press the combo box to bring up the menu */
+
+  do_accessible_action (combo_box_a, "press");
+  sleep_in_main_loop (); /* have to wait because bringing up the menu is asynchronous... */
+
+  /* Get the menu from the combo box; it's the first child */
+
+  menu_a = atk_object_ref_accessible_child (combo_box_a, 0);
+  g_assert (atk_object_get_role (menu_a) == ATK_ROLE_MENU);
+
+  /* Check that the last item in the menu is the "Other…" one */
+
+  num_items = atk_object_get_n_accessible_children (menu_a);
+  g_assert (num_items > 0);
+
+  other_index = num_items - 1;
+
+  item_a = atk_object_ref_accessible_child (menu_a, other_index);
+  g_assert_cmpstr (atk_object_get_name (item_a), ==, "Other…");  /* FIXME: how do we translate this? */
+
+  /* Activate the item */
+
+  do_accessible_action (item_a, "click");
+
+  /* Cancel the dialog */
+
+  sleep_in_main_loop ();
+  fc_dialog = get_file_chooser_dialog_from_button (GTK_FILE_CHOOSER_BUTTON (w.fc_button));
+
+  gtk_dialog_response (GTK_DIALOG (fc_dialog), GTK_RESPONSE_CANCEL);
+
+  /* Now check the selection in the combo box */
+  check_that_basename_is_shown (GTK_FILE_CHOOSER_BUTTON (w.fc_button), FOLDER_NAME);
+
+  gtk_widget_destroy (w.window);
+}
+
+static void
+setup_file_chooser_button_combo_box_tests (void)
+{
+  g_test_add_func ("/GtkFileChooserButton/combo_box-1", test_file_chooser_button_combo_box_1);
+}
+
+static FileChooserButtonTest button_tests[] =
+  {
+    /* OPEN tests without dialog */
+
+    {
+      "open-1",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-2",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-3",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME,               /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-4",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME_2,             /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME_2              /* final_filename */
+    },
+    {
+      "open-5",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-6",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME_2,           /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+
+    /* SELECT_FOLDER tests without dialog */
+
+    {
+      "select-folder-1",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-2",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-3",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+    {
+      "select-folder-4",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-5",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-6",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+    {
+      "select-folder-7",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME_2,           /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-8",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      0,                       /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+
+    /* OPEN tests with dialog, cancelled
+     *
+     * Test names are "open-dialog-cancel-A-B", where A and B can be:
+     *
+     *   A:
+     *      ni - no initial filename
+     *       i - initial filename
+     *      nf - no initial folder
+     *       f - initial folder
+     *
+     *   B:
+     *      nt - no tweaks
+     *       b - tweak button
+     *       d - tweak dialog
+     */
+
+    {
+      "open-dialog-cancel-ni-nt",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-ni-b",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME,               /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-dialog-cancel-ni-d",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME,               /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-i-nt",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-dialog-cancel-i-b",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME_2,             /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME_2              /* final_filename */
+    },
+    {
+      "open-dialog-cancel-i-d",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME_2,             /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-dialog-cancel-nf-nt",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-nf-b",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME,             /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-nf-d",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      FOLDER_NAME,             /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-f-nt",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-f-b",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME_2,           /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "open-dialog-cancel-f-d",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+
+    /* SELECT_FOLDER tests with dialog, cancelled */
+
+    {
+      "select-folder-dialog-cancel-ni-nt",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-ni-b",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME,             /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-ni-d",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME,             /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-i-nt",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-i-b",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-i-d",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-nf-nt",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-nf-b",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME,             /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-nf-d",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      FOLDER_NAME,             /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-f-nt",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-f-nt-2",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-f-b",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME_2,           /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-f-b-2",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-f-d",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      FOLDER_NAME_2,           /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "select-folder-dialog-cancel-f-d-2",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      DIALOG,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      GTK_RESPONSE_CANCEL,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      FOLDER_NAME,             /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+
+    /* OPEN tests with dialog */
+
+    {
+      "open-dialog-1",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME,               /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-dialog-2",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+    {
+      "open-dialog-3",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME_2,             /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME_2              /* final_filename */
+    },
+    {
+      "open-dialog-4",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME,               /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FILE_NAME                        /* final_filename */
+    },
+
+    /* SELECT_FOLDER tests with dialog */
+
+    {
+      "select-folder-dialog-1",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-dialog-2",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME              /* final_filename */
+    },
+    {
+      "select-folder-dialog-3",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+    {
+      "select-folder-dialog-4",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      FOLDER_NAME,             /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      TRUE,                    /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      GTK_RESPONSE_ACCEPT,     /* dialog_response */
+      FALSE,                   /* unselect_all */
+      NULL,                    /* final_current_folder */
+      FOLDER_NAME_2            /* final_filename */
+    },
+
+    /* Unselection tests */
+    {
+      "unselect-all-1",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-2",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-3",
+      GTK_FILE_CHOOSER_ACTION_OPEN,
+      NULL,                    /* initial_current_folder */
+      FILE_NAME,               /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FILE_NAME_2,             /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-4",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      NULL,                    /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-5",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      NULL,                    /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+    {
+      "unselect-all-6",
+      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+      NULL,                    /* initial_current_folder */
+      FOLDER_NAME,             /* initial_filename */
+      FALSE,                   /* open_dialog */
+      BUTTON,                  /* what_to_tweak */
+      NULL,                    /* tweak_current_folder */
+      FOLDER_NAME_2,           /* tweak_filename */
+      0,                       /* dialog_response */
+      TRUE,                    /* unselect_all */
+      NULL,                    /* final_current_folder */
+      NULL                     /* final_filename */
+    },
+
+  };
+
+static void
+setup_file_chooser_button_tests (void)
+{
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (button_tests); i++)
+    {
+      char *test_name;
+
+      test_name = make_button_test_name (&button_tests[i]);
+      g_test_add_data_func (test_name, &button_tests[i], test_file_chooser_button);
+      g_free (test_name);
+    }
+
+  setup_file_chooser_button_combo_box_tests ();
+}
+
+#ifdef BROKEN_TESTS
+struct confirm_overwrite_closure {
+  GtkWidget *chooser;
+  GtkWidget *accept_button;
+  gint confirm_overwrite_signal_emitted;
+  gchar *extension;
+};
+
+static GtkFileChooserConfirmation
+confirm_overwrite_cb (GtkFileChooser *chooser, gpointer data)
+{
+  struct confirm_overwrite_closure *closure = data;
+
+  if (g_test_verbose())
+    printf ("bling!\n");
+  closure->confirm_overwrite_signal_emitted += 1;
+
+  return GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME;
+}
+
+static void
+overwrite_response_cb (GtkFileChooser *chooser, gint response, gpointer data)
+{
+  struct confirm_overwrite_closure *closure = data;
+  char *filename;
+
+  if (g_test_verbose())
+    printf ("plong!\n");
+
+  if (response != GTK_RESPONSE_ACCEPT)
+    return;
+
+  filename = gtk_file_chooser_get_filename (chooser);
+
+  if (!g_str_has_suffix (filename, closure->extension))
+    {
+      char *basename;
+
+      basename = g_path_get_basename (filename);
+      g_free (filename);
+
+      filename = g_strconcat (basename, closure->extension, NULL);
+      gtk_file_chooser_set_current_name (chooser, filename);
+
+      g_signal_stop_emission_by_name (chooser, "response");
+      gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
+    }
+}
+
+static gboolean
+confirm_overwrite_timeout_cb (gpointer data)
+{
+  struct confirm_overwrite_closure *closure;
+
+  closure = data;
+  gtk_button_clicked (GTK_BUTTON (closure->accept_button));
+
+  return FALSE;
+}
+
+/* http://bugzilla.gnome.org/show_bug.cgi?id=347883 */
+static gboolean
+test_confirm_overwrite_for_path (const char *path, gboolean append_extension)
+{
+  gboolean passed;
+  struct confirm_overwrite_closure closure;
+  char *filename;
+  guint timeout_id;
+
+  passed = TRUE;
+
+  closure.extension = NULL;
+  closure.confirm_overwrite_signal_emitted = 0;
+  closure.chooser = gtk_file_chooser_dialog_new ("hello", NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
+                                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                                NULL);
+  closure.accept_button = gtk_dialog_add_button (GTK_DIALOG (closure.chooser),
+                                                 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT);
+  gtk_dialog_set_default_response (GTK_DIALOG (closure.chooser), GTK_RESPONSE_ACCEPT);
+
+  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (closure.chooser), TRUE);
+
+  g_signal_connect (closure.chooser, "confirm-overwrite",
+                   G_CALLBACK (confirm_overwrite_cb), &closure);
+
+  if (append_extension)
+    {
+      char *extension;
+
+      filename = g_path_get_dirname (path);
+      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (closure.chooser), filename);
+      g_free (filename);
+
+      filename = g_path_get_basename (path);
+      extension = strchr (filename, '.');
+
+      if (extension)
+        {
+          closure.extension = g_strdup (extension);
+          *extension = '\0';
+        }
+
+      gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (closure.chooser), filename);
+      g_free (filename);
+
+      g_signal_connect (closure.chooser, "response",
+                        G_CALLBACK (overwrite_response_cb), &closure);
+    }
+  else
+    {
+      gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (closure.chooser), path);
+    }
+
+  timeout_id = gdk_threads_add_timeout_full (G_MAXINT, SLEEP_DURATION, confirm_overwrite_timeout_cb, &closure, NULL);
+  gtk_dialog_run (GTK_DIALOG (closure.chooser));
+  g_source_remove (timeout_id);
+
+  filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (closure.chooser));
+  passed = passed && filename && (strcmp (filename, path) == 0);
+  g_free (filename);
+
+  gtk_widget_destroy (closure.chooser);
+
+  passed = passed && (1 == closure.confirm_overwrite_signal_emitted);
+
+  log_test (passed, "Confirm overwrite for %s", path);
+
+  return passed;
+}
+
+static void
+test_confirm_overwrite (void)
+{
+  gboolean passed = TRUE;
+
+  /* first test for a file we know will always exist */
+  passed = passed && test_confirm_overwrite_for_path ("/etc/passwd", FALSE);
+  g_assert (passed);
+  passed = passed && test_confirm_overwrite_for_path ("/etc/resolv.conf", TRUE);
+  g_assert (passed);
+}
+#endif
+
+static const GtkFileChooserAction open_actions[] = {
+  GTK_FILE_CHOOSER_ACTION_OPEN,
+  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
+};
+
+static const GtkFileChooserAction save_actions[] = {
+  GTK_FILE_CHOOSER_ACTION_SAVE,
+  GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
+};
+
+
+#ifdef BROKEN_TESTS
+static gboolean
+has_action (const GtkFileChooserAction *actions,
+           int n_actions,
+           GtkFileChooserAction sought_action)
+{
+  int i;
+
+  for (i = 0; i < n_actions; i++)
+    if (actions[i] == sought_action)
+      return TRUE;
+
+  return FALSE;
+}
+
+static GtkFileChooserDefault *
+get_impl_from_dialog (GtkWidget *dialog)
+{
+  GtkFileChooserDialog *d;
+  GtkFileChooserDialogPrivate *dialog_priv;
+  GtkFileChooserWidget *chooser_widget;
+  GtkFileChooserWidgetPrivate *widget_priv;
+  GtkFileChooserDefault *impl;
+
+  d = GTK_FILE_CHOOSER_DIALOG (dialog);
+  dialog_priv = d->priv;
+  chooser_widget = GTK_FILE_CHOOSER_WIDGET (dialog_priv->widget);
+  if (!chooser_widget)
+    g_error ("BUG: dialog_priv->widget is not a GtkFileChooserWidget");
+
+  widget_priv = chooser_widget->priv;
+  impl = (GtkFileChooserDefault *) (widget_priv->impl);
+  if (!impl)
+    g_error ("BUG: widget_priv->impl is not a GtkFileChooserDefault");
+
+  return impl;
+}
+
+static gboolean
+test_widgets_for_current_action (GtkFileChooserDialog *dialog,
+                                GtkFileChooserAction  expected_action)
+{
+  GtkFileChooserDefault *impl;
+  gboolean passed;
+
+  if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) != expected_action)
+    return FALSE;
+
+  impl = get_impl_from_dialog (GTK_WIDGET (dialog));
+
+  g_assert (impl->action == expected_action);
+
+  passed = TRUE;
+
+  /* OPEN implies that the "new folder" button is hidden; otherwise it is shown */
+  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
+    passed = passed && !gtk_widget_get_visible (impl->browse_new_folder_button);
+  else
+    passed = passed && gtk_widget_get_visible (impl->browse_new_folder_button);
+
+  /* Check that the widgets are present/visible or not */
+  if (has_action (open_actions, G_N_ELEMENTS (open_actions), impl->action))
+    {
+      passed = passed && (impl->save_widgets == NULL
+                         && (impl->location_mode == LOCATION_MODE_PATH_BAR
+                             ? impl->location_entry == NULL
+                             : impl->location_entry != NULL)
+                         && impl->save_folder_label == NULL
+                         && impl->save_folder_combo == NULL
+                         && impl->save_expander == NULL
+                         && GTK_IS_CONTAINER (impl->browse_widgets) && gtk_widget_is_drawable (impl->browse_widgets));
+    }
+  else if (has_action (save_actions, G_N_ELEMENTS (save_actions), impl->action))
+    {
+      /* FIXME: we can't use GTK_IS_FILE_CHOOSER_ENTRY() because it uses
+       * _gtk_file_chooser_entry_get_type(), which is a non-exported symbol.
+       * So, we just test impl->location_entry for being non-NULL
+       */
+      passed = passed && (GTK_IS_CONTAINER (impl->save_widgets) && gtk_widget_is_drawable (impl->save_widgets)
+                         && impl->location_entry != NULL && gtk_widget_is_drawable (impl->location_entry)
+                         && GTK_IS_LABEL (impl->save_folder_label) && gtk_widget_is_drawable (impl->save_folder_label)
+                         && GTK_IS_COMBO_BOX (impl->save_folder_combo) && gtk_widget_is_drawable (impl->save_folder_combo)
+                         && GTK_IS_EXPANDER (impl->save_expander) && gtk_widget_is_drawable (impl->save_expander)
+                         && GTK_IS_CONTAINER (impl->browse_widgets));
+
+      /* FIXME: we are in a SAVE mode; test the visibility and sensitivity of
+       * the children that change depending on the state of the expander.
+       */
+    }
+  else
+    {
+      g_error ("BAD TEST: test_widgets_for_current_action() doesn't know about %s", get_action_name (impl->action));
+      passed = FALSE;
+    }
+
+  return passed;
+}
+
+typedef gboolean (* ForeachActionCallback) (GtkFileChooserDialog *dialog,
+                                           GtkFileChooserAction  action,
+                                           gpointer              user_data);
+
+static gboolean
+foreach_action (GtkFileChooserDialog *dialog,
+               ForeachActionCallback callback,
+               gpointer              user_data)
+{
+  GEnumClass *enum_class;
+  int i;
+
+  enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION);
+  if (!enum_class)
+    g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION");
+
+  for (i = 0; i < enum_class->n_values; i++)
+    {
+      GEnumValue *enum_value;
+      GtkFileChooserAction action;
+      gboolean passed;
+
+      enum_value = enum_class->values + i;
+      action = enum_value->value;
+
+      passed = (* callback) (dialog, action, user_data);
+      if (!passed)
+       return FALSE;
+    }
+
+  return TRUE;
+}
+
+struct action_closure {
+  GtkFileChooserAction from_action;
+};
+
+static gboolean
+switch_from_to_action_cb (GtkFileChooserDialog *dialog,
+                         GtkFileChooserAction  action,
+                         gpointer              user_data)
+{
+  struct action_closure *closure;
+  gboolean passed;
+
+  closure = user_data;
+
+  gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), closure->from_action);
+
+  passed = test_widgets_for_current_action (dialog, closure->from_action);
+  log_test (passed, "switch_from_to_action_cb(): reset to action %s", get_action_name (closure->from_action));
+  if (!passed)
+    return FALSE;
+
+  gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), action);
+
+  passed = test_widgets_for_current_action (dialog, action);
+  log_test (passed, "switch_from_to_action_cb(): transition from %s to %s",
+           get_action_name (closure->from_action),
+           get_action_name (action));
+  return passed;
+}
+
+static gboolean
+switch_from_action_cb (GtkFileChooserDialog *dialog,
+                      GtkFileChooserAction  action,
+                      gpointer              user_data)
+{
+  struct action_closure closure;
+
+  closure.from_action = action;
+
+  return foreach_action (dialog, switch_from_to_action_cb, &closure);
+}
+
+static void
+test_action_widgets (void)
+{
+  GtkWidget *dialog;
+  GtkFileChooserAction action;
+  gboolean passed;
+
+  dialog = gtk_file_chooser_dialog_new ("Test file chooser",
+                                       NULL,
+                                       GTK_FILE_CHOOSER_ACTION_OPEN,
+                                       GTK_STOCK_CANCEL,
+                                       GTK_RESPONSE_CANCEL,
+                                       GTK_STOCK_OK,
+                                       GTK_RESPONSE_ACCEPT,
+                                       NULL);
+  gtk_widget_show_now (dialog);
+
+  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog));
+
+  passed = test_widgets_for_current_action (GTK_FILE_CHOOSER_DIALOG (dialog), action);
+  log_test (passed, "test_action_widgets(): widgets for initial action %s", get_action_name (action));
+  g_assert (passed);
+
+  passed = foreach_action (GTK_FILE_CHOOSER_DIALOG (dialog), switch_from_action_cb, NULL);
+  log_test (passed, "test_action_widgets(): all transitions through property change");
+  g_assert (passed);
+
+  gtk_widget_destroy (dialog);
+}
+#endif
+
+#ifdef BROKEN_TESTS
+static gboolean
+test_reload_sequence (gboolean set_folder_before_map)
+{
+  GtkWidget *dialog;
+  GtkFileChooserDefault *impl;
+  gboolean passed;
+  char *folder;
+  char *current_working_dir;
+
+  passed = TRUE;
+
+  current_working_dir = g_get_current_dir ();
+
+  dialog = gtk_file_chooser_dialog_new ("Test file chooser",
+                                       NULL,
+                                       GTK_FILE_CHOOSER_ACTION_OPEN,
+                                       GTK_STOCK_CANCEL,
+                                       GTK_RESPONSE_CANCEL,
+                                       GTK_STOCK_OK,
+                                       GTK_RESPONSE_ACCEPT,
+                                       NULL);
+  impl = get_impl_from_dialog (dialog);
+
+  if (set_folder_before_map)
+    {
+      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
+
+      wait_for_idle ();
+
+      passed = passed && (impl->current_folder != NULL
+                         && impl->browse_files_model != NULL
+                         && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
+                         && impl->reload_state == RELOAD_HAS_FOLDER
+                         && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
+                         && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
+                             ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
+                             : TRUE));
+
+      wait_for_idle ();
+
+      folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+      passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
+      g_free (folder);
+    }
+  else
+    {
+      /* Initially, no folder is not loaded or pending */
+      passed = passed && (impl->current_folder == NULL
+                         && impl->sort_model == NULL
+                         && impl->browse_files_model == NULL
+                         && impl->load_state == LOAD_EMPTY
+                         && impl->reload_state == RELOAD_EMPTY
+                         && impl->load_timeout_id == 0);
+
+      wait_for_idle ();
+
+      folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+      passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
+    }
+
+  log_test (passed, "test_reload_sequence(): initial status");
+
+  /* After mapping, it is loading some folder, either the one that was explicitly set or the default one */
+
+  gtk_widget_show_now (dialog);
+
+  wait_for_idle ();
+
+  passed = passed && (impl->current_folder != NULL
+                     && impl->browse_files_model != NULL
+                     && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
+                     && impl->reload_state == RELOAD_HAS_FOLDER
+                     && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
+                     && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
+                         ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
+                         : TRUE));
+
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+  if (set_folder_before_map)
+    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
+  else
+    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
+
+  g_free (folder);
+
+  log_test (passed, "test_reload_sequence(): status after map");
+
+  /* Unmap it; we should still have a folder */
+
+  gtk_widget_hide (dialog);
+
+  wait_for_idle ();
+
+  passed = passed && (impl->current_folder != NULL
+                     && impl->browse_files_model != NULL
+                     && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
+                     && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
+                     && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
+                         ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
+                         : TRUE));
+
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+  if (set_folder_before_map)
+    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
+  else
+    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
+
+  g_free (folder);
+
+  log_test (passed, "test_reload_sequence(): status after unmap");
+
+  /* Map it again! */
+
+  gtk_widget_show_now (dialog);
+
+  wait_for_idle ();
+
+  passed = passed && (impl->current_folder != NULL
+                     && impl->browse_files_model != NULL
+                     && (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
+                     && impl->reload_state == RELOAD_HAS_FOLDER
+                     && (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
+                     && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
+                         ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
+                         : TRUE));
+
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+  if (set_folder_before_map)
+    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
+  else
+    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
+
+  g_free (folder);
+
+  log_test (passed, "test_reload_sequence(): status after re-map");
+
+  gtk_widget_destroy (dialog);
+  g_free (current_working_dir);
+
+  return passed;
+}
+
+static void
+test_reload (void)
+{
+  gboolean passed;
+
+  passed = test_reload_sequence (FALSE);
+  log_test (passed, "test_reload(): create and use the default folder");
+  g_assert (passed);
+
+  passed = test_reload_sequence (TRUE);
+  log_test (passed, "test_reload(): set a folder explicitly before mapping");
+  g_assert (passed);
+}
+
+static gboolean
+test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_dialog, gboolean set_folder_on_dialog)
+{
+  gboolean passed;
+  GtkWidget *window;
+  GtkWidget *button;
+  char *folder;
+  GtkWidget *dialog;
+  char *current_working_dir;
+  gboolean must_have_cwd;
+
+  passed = TRUE;
+
+  current_working_dir = g_get_current_dir ();
+  must_have_cwd = !(use_dialog && set_folder_on_dialog);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  if (use_dialog)
+    {
+      dialog = gtk_file_chooser_dialog_new ("Test", NULL, action,
+                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                           GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                                           NULL);
+      button = gtk_file_chooser_button_new_with_dialog (dialog);
+
+      if (set_folder_on_dialog)
+       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
+    }
+  else
+    {
+      button = gtk_file_chooser_button_new ("Test", action);
+      dialog = NULL; /* keep gcc happy */
+    }
+
+  gtk_container_add (GTK_CONTAINER (window), button);
+
+  /* Pre-map; no folder is set */
+  wait_for_idle ();
+
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
+  if (must_have_cwd)
+    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
+  else
+    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
+
+  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, pre-map, %s",
+           get_action_name (action),
+           use_dialog,
+           set_folder_on_dialog,
+           must_have_cwd ? "must have $cwd" : "must have explicit folder");
+
+  /* Map; folder should be set */
+
+  gtk_widget_show_all (window);
+  gtk_widget_show_now (window);
+
+  wait_for_idle ();
+
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
+
+  if (must_have_cwd)
+    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
+  else
+    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
+
+  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, mapped, %s",
+           get_action_name (action),
+           use_dialog,
+           set_folder_on_dialog,
+           must_have_cwd ? "must have $cwd" : "must have explicit folder");
+  g_free (folder);
+
+  /* Unmap; folder should be set */
+
+  gtk_widget_hide (window);
+  wait_for_idle ();
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
+
+  if (must_have_cwd)
+    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
+  else
+    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
+
+  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, unmapped, %s",
+           get_action_name (action),
+           use_dialog,
+           set_folder_on_dialog,
+           must_have_cwd ? "must have $cwd" : "must have explicit folder");
+  g_free (folder);
+
+  /* Re-map; folder should be set */
+
+  gtk_widget_show_now (window);
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
+
+  if (must_have_cwd)
+    passed = passed && (g_strcmp0 (folder, current_working_dir) == 0);
+  else
+    passed = passed && (g_strcmp0 (folder, g_get_home_dir()) == 0);
+  wait_for_idle ();
+  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, re-mapped, %s",
+           get_action_name (action),
+           use_dialog,
+           set_folder_on_dialog,
+           must_have_cwd ? "must have $cwd" : "must have explicit folder");
+  g_free (folder);
+
+  g_free (current_working_dir);
+
+  gtk_widget_destroy (window);
+
+  return passed;
+}
+
+static void
+test_button_folder_states (void)
+{
+  /* GtkFileChooserButton only supports OPEN and SELECT_FOLDER */
+  static const GtkFileChooserAction actions_to_test[] = {
+    GTK_FILE_CHOOSER_ACTION_OPEN,
+    GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
+  };
+  gboolean passed;
+  int i;
+
+  passed = TRUE;
+
+  for (i = 0; i < G_N_ELEMENTS (actions_to_test); i++)
+    {
+      passed = passed && test_button_folder_states_for_action (actions_to_test[i], FALSE, FALSE);
+      g_assert (passed);
+      passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, FALSE);
+      g_assert (passed);
+      passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, TRUE);
+      g_assert (passed);
+      log_test (passed, "test_button_folder_states(): action %s", get_action_name (actions_to_test[i]));
+    }
+
+  log_test (passed, "test_button_folder_states(): all supported actions");
+}
+
+static void
+test_folder_switch_and_filters (void)
+{
+  gboolean passed;
+  char *cwd;
+  char *base_dir;
+  GFile *cwd_file;
+  GFile *base_dir_file;
+  GtkWidget *dialog;
+  GtkFileFilter *all_filter;
+  GtkFileFilter *txt_filter;
+  GtkFileChooserDefault *impl;
+
+  passed = TRUE;
+
+  cwd = g_get_current_dir ();
+  base_dir = g_build_filename (cwd, "file-chooser-test-dir", NULL);
+
+  dialog = gtk_file_chooser_dialog_new ("Test", NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
+                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                                       NULL);
+  impl = get_impl_from_dialog (dialog);
+
+  cwd_file = g_file_new_for_path (cwd);
+  base_dir_file = g_file_new_for_path (base_dir);
+
+  passed = passed && gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
+  g_assert (passed);
+
+  /* All files filter */
+
+  all_filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (all_filter, "All files");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_filter);
+
+  /* *.txt filter */
+
+  txt_filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (all_filter, "*.txt");
+  gtk_file_filter_add_pattern (txt_filter, "*.txt");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
+
+  /* Test filter set */
+
+  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), all_filter);
+  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == all_filter);
+  g_assert (passed);
+
+  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), txt_filter);
+  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
+  log_test (passed, "test_folder_switch_and_filters(): set and get filter");
+  g_assert (passed);
+
+  gtk_widget_show (dialog);
+
+  /* Test that filter is unchanged when we switch folders */
+
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd);
+  sleep_in_main_loop ();
+  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
+  g_assert (passed);
+
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
+  sleep_in_main_loop ();
+
+  g_signal_emit_by_name (impl->browse_path_bar, "path-clicked",
+                        cwd_file,
+                        base_dir_file,
+                        FALSE);
+  sleep_in_main_loop ();
+  passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
+  log_test (passed, "test_folder_switch_and_filters(): filter after changing folder");
+  g_assert (passed);
+
+  /* cleanups */
+  g_free (cwd);
+  g_free (base_dir);
+  g_object_unref (cwd_file);
+  g_object_unref (base_dir_file);
+
+  gtk_widget_destroy (dialog);
+
+  log_test (passed, "test_folder_switch_and_filters(): all filter tests");
+}
+#endif
+
+int
+main (int    argc,
+      char **argv)
+{
+  /* initialize test program */
+  gtk_test_init (&argc, &argv);
+
+  /* Register tests */
+
+  setup_file_chooser_button_tests ();
+#ifdef BROKEN_TESTS
+  setup_set_filename_tests ();
+  setup_set_current_name_tests ();
+
+  g_test_add_func ("/GtkFileChooser/confirm_overwrite", test_confirm_overwrite);
+  g_test_add_func ("/GtkFileChooser/action_widgets", test_action_widgets);
+  g_test_add_func ("/GtkFileChooser/reload", test_reload);
+  g_test_add_func ("/GtkFileChooser/button_folder_states", test_button_folder_states);
+  g_test_add_func ("/GtkFileChooser/folder_switch_and_filters", test_folder_switch_and_filters);
+#endif
+
+  /* run and check selected tests */
+  return g_test_run();
+}
diff --git a/testsuite/gtk/filtermodel.c b/testsuite/gtk/filtermodel.c
new file mode 100644 (file)
index 0000000..dcacf8d
--- /dev/null
@@ -0,0 +1,7147 @@
+/* Extensive GtkTreeModelFilter tests.
+ * Copyright (C) 2009,2011  Kristian Rietveld  <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include "treemodel.h"
+#include "gtktreemodelrefcount.h"
+
+/* Left to do:
+ *   - Proper coverage checking to see if the unit tests cover
+ *     all possible cases.
+ *   - Check if the iterator stamp is incremented at the correct times.
+ *
+ * For more thorough testing:
+ *   - Test with randomized models.
+ *   - Extensively test a filter model wrapping a sort model,
+ *     or a sort model wrapping a filter model by:
+ *       # Checking structure.
+ *       # Checking for correct signals emissions.
+ *       # Checking correct reference counting.
+ *       # Tests should be done with the sort and filter model
+ *         in various filtering and sorting states.
+ */
+
+
+/*
+ * Model creation
+ */
+
+#define LEVEL_LENGTH 5
+
+static void
+create_tree_store_set_values (GtkTreeStore *store,
+                              GtkTreeIter  *iter,
+                              gboolean      visible)
+{
+  GtkTreePath *path;
+  gchar *path_string;
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
+  path_string = gtk_tree_path_to_string (path);
+
+  gtk_tree_store_set (store, iter,
+                      0, path_string,
+                      1, visible,
+                      -1);
+
+  gtk_tree_path_free (path);
+  g_free (path_string);
+}
+
+static void
+create_tree_store_recurse (int           depth,
+                           GtkTreeStore *store,
+                           GtkTreeIter  *parent,
+                           gboolean      visible)
+{
+  int i;
+
+  for (i = 0; i < LEVEL_LENGTH; i++)
+    {
+      GtkTreeIter iter;
+
+      gtk_tree_store_insert (store, &iter, parent, i);
+      create_tree_store_set_values (store, &iter, visible);
+
+      if (depth > 0)
+        create_tree_store_recurse (depth - 1, store, &iter, visible);
+    }
+}
+
+static GtkTreeStore *
+create_tree_store (int      depth,
+                   gboolean visible)
+{
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+
+  create_tree_store_recurse (depth, store, NULL, visible);
+
+  return store;
+}
+
+/*
+ * Fixture
+ */
+
+typedef struct
+{
+  GtkWidget *tree_view;
+
+  GtkTreeStore *store;
+  GtkTreeModelFilter *filter;
+
+  SignalMonitor *monitor;
+
+  guint block_signals : 1;
+} FilterTest;
+
+
+static void
+filter_test_store_signal (FilterTest *fixture)
+{
+  if (fixture->block_signals)
+    g_signal_stop_emission_by_name (fixture->store, "row-changed");
+}
+
+
+static void
+filter_test_setup_generic (FilterTest    *fixture,
+                           gconstpointer  test_data,
+                           int            depth,
+                           gboolean       empty,
+                           gboolean       unfiltered)
+{
+  const GtkTreePath *vroot = test_data;
+  GtkTreeModel *filter;
+
+  fixture->store = create_tree_store (depth, !empty);
+
+  g_signal_connect_swapped (fixture->store, "row-changed",
+                            G_CALLBACK (filter_test_store_signal), fixture);
+
+  /* Please forgive me for casting const away. */
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
+                                      (GtkTreePath *)vroot);
+  fixture->filter = GTK_TREE_MODEL_FILTER (filter);
+
+  if (!unfiltered)
+    gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
+
+  /* We need a tree view that's listening to get ref counting from that
+   * side.
+   */
+  fixture->tree_view = gtk_tree_view_new_with_model (filter);
+
+  fixture->monitor = signal_monitor_new (filter);
+}
+
+static void
+filter_test_setup_expand_root (FilterTest *fixture)
+{
+  int i;
+  GtkTreePath *path;
+
+  path = gtk_tree_path_new_from_indices (0, -1);
+
+  for (i = 0; i < LEVEL_LENGTH; i++)
+    {
+      gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view),
+                                path, FALSE);
+      gtk_tree_path_next (path);
+    }
+  gtk_tree_path_free (path);
+}
+
+static void
+filter_test_setup (FilterTest    *fixture,
+                   gconstpointer  test_data)
+{
+  filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
+}
+
+static void
+filter_test_setup_empty (FilterTest    *fixture,
+                         gconstpointer  test_data)
+{
+  filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
+}
+
+static void
+filter_test_setup_unfiltered (FilterTest    *fixture,
+                              gconstpointer  test_data)
+{
+  filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
+}
+
+static void
+filter_test_setup_unfiltered_root_expanded (FilterTest    *fixture,
+                                            gconstpointer  test_data)
+{
+  filter_test_setup_unfiltered (fixture, test_data);
+  filter_test_setup_expand_root (fixture);
+}
+
+static void
+filter_test_setup_empty_unfiltered (FilterTest    *fixture,
+                                    gconstpointer  test_data)
+{
+  filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
+}
+
+static void
+filter_test_setup_empty_unfiltered_root_expanded (FilterTest    *fixture,
+                                                  gconstpointer  test_data)
+{
+  filter_test_setup_empty_unfiltered (fixture, test_data);
+  filter_test_setup_expand_root (fixture);
+}
+
+static GtkTreePath *
+strip_virtual_root (GtkTreePath *path,
+                    GtkTreePath *root_path)
+{
+  GtkTreePath *real_path;
+
+  if (root_path)
+    {
+      int j;
+      int depth = gtk_tree_path_get_depth (path);
+      int root_depth = gtk_tree_path_get_depth (root_path);
+
+      real_path = gtk_tree_path_new ();
+
+      for (j = 0; j < depth - root_depth; j++)
+        gtk_tree_path_append_index (real_path,
+                                    gtk_tree_path_get_indices (path)[root_depth + j]);
+    }
+  else
+    real_path = gtk_tree_path_copy (path);
+
+  return real_path;
+}
+
+static int
+count_visible (FilterTest  *fixture,
+               GtkTreePath *store_path)
+{
+  int i;
+  int n_visible = 0;
+  GtkTreeIter iter;
+
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+                           &iter, store_path);
+
+  for (i = 0; i < LEVEL_LENGTH; i++)
+    {
+      gboolean visible;
+
+      gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
+                          1, &visible,
+                          -1);
+
+      if (visible)
+        n_visible++;
+    }
+
+  return n_visible;
+}
+
+static void
+filter_test_append_refilter_signals_recurse (FilterTest  *fixture,
+                                             GtkTreePath *store_path,
+                                             GtkTreePath *filter_path,
+                                             int          depth,
+                                             GtkTreePath *root_path)
+{
+  int i;
+  int rows_deleted = 0;
+  GtkTreeIter iter;
+
+  gtk_tree_path_down (store_path);
+  gtk_tree_path_down (filter_path);
+
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+                           &iter, store_path);
+
+  for (i = 0; i < LEVEL_LENGTH; i++)
+    {
+      gboolean visible;
+      GtkTreePath *real_path;
+
+      gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
+                          1, &visible,
+                          -1);
+
+      if (root_path &&
+          (!gtk_tree_path_is_descendant (store_path, root_path)
+           || !gtk_tree_path_compare (store_path, root_path)))
+        {
+          if (!gtk_tree_path_compare (store_path, root_path))
+            {
+              if (depth > 1
+                  && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
+                                                    &iter))
+                {
+                  GtkTreePath *store_copy;
+                  GtkTreePath *filter_copy;
+
+                  store_copy = gtk_tree_path_copy (store_path);
+                  filter_copy = gtk_tree_path_copy (filter_path);
+                  filter_test_append_refilter_signals_recurse (fixture,
+                                                               store_copy,
+                                                               filter_copy,
+                                                               depth - 1,
+                                                               root_path);
+                  gtk_tree_path_free (store_copy);
+                  gtk_tree_path_free (filter_copy);
+                }
+            }
+
+          gtk_tree_path_next (store_path);
+          gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+
+          if (visible)
+            gtk_tree_path_next (filter_path);
+
+          continue;
+        }
+
+      real_path = strip_virtual_root (filter_path, root_path);
+
+      if (visible)
+        {
+          /* This row will be inserted */
+          signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
+                                             real_path);
+
+          if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
+                                             &iter))
+            {
+              signal_monitor_append_signal_path (fixture->monitor,
+                                                 ROW_HAS_CHILD_TOGGLED,
+                                                 real_path);
+
+              if (depth > 1)
+                {
+                  GtkTreePath *store_copy;
+                  GtkTreePath *filter_copy;
+
+                  store_copy = gtk_tree_path_copy (store_path);
+                  filter_copy = gtk_tree_path_copy (filter_path);
+                  filter_test_append_refilter_signals_recurse (fixture,
+                                                               store_copy,
+                                                               filter_copy,
+                                                               depth - 1,
+                                                               root_path);
+                  gtk_tree_path_free (store_copy);
+                  gtk_tree_path_free (filter_copy);
+                }
+              else if (depth == 1)
+                {
+                  GtkTreePath *tmp_path;
+
+                  /* If all child rows are invisible, then the last row to
+                   * become invisible will emit row-has-child-toggled on the
+                   * parent.
+                   */
+
+                  tmp_path = gtk_tree_path_copy (store_path);
+                  gtk_tree_path_append_index (tmp_path, 0);
+
+                  if (count_visible (fixture, tmp_path) == 0)
+                    signal_monitor_append_signal_path (fixture->monitor,
+                                                       ROW_HAS_CHILD_TOGGLED,
+                                                       real_path);
+
+                  gtk_tree_path_free (tmp_path);
+                }
+            }
+
+          gtk_tree_path_next (filter_path);
+        }
+      else
+        {
+          /* This row will be deleted */
+          rows_deleted++;
+          signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
+                                             real_path);
+        }
+
+      gtk_tree_path_free (real_path);
+
+      gtk_tree_path_next (store_path);
+      gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+    }
+
+  if (rows_deleted == LEVEL_LENGTH
+      && gtk_tree_path_get_depth (filter_path) > 1)
+    {
+      GtkTreePath *real_path;
+
+      gtk_tree_path_up (store_path);
+      gtk_tree_path_up (filter_path);
+
+      /* A row-has-child-toggled will be emitted on the parent */
+      if (!root_path
+          || (root_path
+              && gtk_tree_path_is_descendant (store_path, root_path)
+              && gtk_tree_path_compare (store_path, root_path)))
+        {
+          real_path = strip_virtual_root (filter_path, root_path);
+          signal_monitor_append_signal_path (fixture->monitor,
+                                             ROW_HAS_CHILD_TOGGLED,
+                                             real_path);
+
+          gtk_tree_path_free (real_path);
+        }
+    }
+}
+
+static void
+filter_test_append_refilter_signals (FilterTest *fixture,
+                                     int         depth)
+{
+  /* A special function that walks the tree store like the
+   * model validation functions below.
+   */
+  GtkTreePath *path;
+  GtkTreePath *filter_path;
+
+  path = gtk_tree_path_new ();
+  filter_path = gtk_tree_path_new ();
+  filter_test_append_refilter_signals_recurse (fixture,
+                                               path,
+                                               filter_path,
+                                               depth,
+                                               NULL);
+  gtk_tree_path_free (path);
+  gtk_tree_path_free (filter_path);
+}
+
+static void
+filter_test_append_refilter_signals_with_vroot (FilterTest  *fixture,
+                                                int          depth,
+                                                GtkTreePath *root_path)
+{
+  /* A special function that walks the tree store like the
+   * model validation functions below.
+   */
+  GtkTreePath *path;
+  GtkTreePath *filter_path;
+
+  path = gtk_tree_path_new ();
+  filter_path = gtk_tree_path_new ();
+  filter_test_append_refilter_signals_recurse (fixture,
+                                               path,
+                                               filter_path,
+                                               depth,
+                                               root_path);
+  gtk_tree_path_free (path);
+  gtk_tree_path_free (filter_path);
+}
+
+static void
+filter_test_enable_filter (FilterTest *fixture)
+{
+  gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
+  gtk_tree_model_filter_refilter (fixture->filter);
+}
+
+static void
+filter_test_block_signals (FilterTest *fixture)
+{
+  fixture->block_signals = TRUE;
+}
+
+static void
+filter_test_unblock_signals (FilterTest *fixture)
+{
+  fixture->block_signals = FALSE;
+}
+
+static void
+filter_test_teardown (FilterTest    *fixture,
+                      gconstpointer  test_data)
+{
+  signal_monitor_free (fixture->monitor);
+
+  gtk_widget_destroy (fixture->tree_view);
+
+  g_object_unref (fixture->filter);
+  g_object_unref (fixture->store);
+}
+
+/*
+ * Model structure validation
+ */
+
+static void
+check_filter_model_recurse (FilterTest  *fixture,
+                            GtkTreePath *store_parent_path,
+                            GtkTreePath *filter_parent_path)
+{
+  int i;
+  GtkTreeIter store_iter;
+  GtkTreeIter filter_iter;
+  gboolean store_has_next, filter_has_next;
+
+  gtk_tree_path_down (store_parent_path);
+  gtk_tree_path_down (filter_parent_path);
+
+  store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+                                            &store_iter, store_parent_path);
+  filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
+                                             &filter_iter, filter_parent_path);
+
+  for (i = 0; i < LEVEL_LENGTH; i++)
+    {
+      gboolean visible;
+
+      g_return_if_fail (store_has_next == TRUE);
+
+      gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
+                          &store_iter,
+                          1, &visible,
+                          -1);
+
+      if (visible)
+        {
+          GtkTreePath *tmp;
+          gchar *filter_str, *store_str;
+
+          g_return_if_fail (filter_has_next == TRUE);
+
+          /* Verify path */
+          tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
+                                         &filter_iter);
+          g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
+
+          /* Verify model content */
+          gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
+                              &store_iter,
+                              0, &store_str,
+                              -1);
+          gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
+                              &filter_iter,
+                              0, &filter_str,
+                              -1);
+
+          g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
+
+          g_free (store_str);
+          g_free (filter_str);
+
+          if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
+                                             &filter_iter))
+            {
+              g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
+
+              check_filter_model_recurse (fixture,
+                                          gtk_tree_path_copy (store_parent_path),
+                                          tmp);
+            }
+          else
+            /* Only when we do not recurse we need to free tmp */
+            gtk_tree_path_free (tmp);
+
+          gtk_tree_path_next (filter_parent_path);
+          filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
+        }
+
+      gtk_tree_path_next (store_parent_path);
+      store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
+    }
+
+  /* Both models should have no more content! */
+  g_return_if_fail (store_has_next == FALSE);
+  g_return_if_fail (filter_has_next == FALSE);
+
+  gtk_tree_path_free (store_parent_path);
+  gtk_tree_path_free (filter_parent_path);
+}
+
+static void
+check_filter_model (FilterTest *fixture)
+{
+  GtkTreePath *path;
+
+  if (fixture->monitor)
+    signal_monitor_assert_is_empty (fixture->monitor);
+
+  path = gtk_tree_path_new ();
+
+  check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
+}
+
+static void
+check_filter_model_with_root (FilterTest  *fixture,
+                              GtkTreePath *path)
+{
+  if (fixture->monitor)
+    signal_monitor_assert_is_empty (fixture->monitor);
+
+  check_filter_model_recurse (fixture,
+                              gtk_tree_path_copy (path),
+                              gtk_tree_path_new ());
+}
+
+/* Helpers */
+
+static void
+check_level_length (GtkTreeModelFilter *filter,
+                    const gchar        *level,
+                    const int           expected_length)
+{
+  if (!level)
+    {
+      int model_length;
+
+      model_length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
+      g_assert_cmpint (model_length, ==, expected_length);
+    }
+  else
+    {
+      int model_length;
+      gboolean retrieved_iter = FALSE;
+      GtkTreeIter iter;
+
+      retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
+                                                            &iter, level);
+      g_return_if_fail (retrieved_iter);
+      model_length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
+      g_assert_cmpint (model_length, ==, expected_length);
+    }
+}
+
+static void
+set_path_visibility (FilterTest  *fixture,
+                     const gchar *path,
+                     gboolean     visible)
+{
+  GtkTreeIter store_iter;
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &store_iter, path);
+  gtk_tree_store_set (fixture->store, &store_iter,
+                      1, visible,
+                      -1);
+}
+
+#if 0
+static void
+insert_path_with_visibility (FilterTest  *fixture,
+                             const gchar *path_string,
+                             gboolean     visible)
+{
+  int position;
+  GtkTreePath *path;
+  GtkTreeIter parent, iter;
+
+  path = gtk_tree_path_new_from_string (path_string);
+  position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
+  gtk_tree_path_up (path);
+
+  if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
+    {
+      gtk_tree_store_insert (fixture->store, &iter, &parent, position);
+      create_tree_store_set_values (fixture->store, &iter, visible);
+    }
+  gtk_tree_path_free (path);
+}
+#endif
+
+/*
+ * The actual tests.
+ */
+
+static void
+verify_test_suite (FilterTest    *fixture,
+                   gconstpointer  user_data)
+{
+  check_filter_model (fixture);
+}
+
+static void
+verify_test_suite_vroot (FilterTest    *fixture,
+                         gconstpointer  user_data)
+{
+  check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
+}
+
+
+static void
+filled_hide_root_level (FilterTest    *fixture,
+                        gconstpointer  user_data)
+{
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
+  set_path_visibility (fixture, "2", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  set_path_visibility (fixture, "0", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
+  set_path_visibility (fixture, "4", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
+
+
+  /* Hide remaining */
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+
+  set_path_visibility (fixture, "1", FALSE);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
+
+  set_path_visibility (fixture, "3", FALSE);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
+
+  check_filter_model (fixture);
+
+  /* Show some */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
+  set_path_visibility (fixture, "1", TRUE);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
+
+  set_path_visibility (fixture, "3", TRUE);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
+
+  check_filter_model (fixture);
+}
+
+static void
+filled_hide_child_levels (FilterTest    *fixture,
+                          gconstpointer  user_data)
+{
+  set_path_visibility (fixture, "0:2", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
+
+  set_path_visibility (fixture, "0:4", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "0:4:3", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "0:4:0", FALSE);
+  set_path_visibility (fixture, "0:4:1", FALSE);
+  set_path_visibility (fixture, "0:4:2", FALSE);
+  set_path_visibility (fixture, "0:4:4", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
+  set_path_visibility (fixture, "0:4", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, "0:3", 0);
+
+  set_path_visibility (fixture, "0:2", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0:4", 0);
+
+  /* Once 0:4:0 got inserted, 0:4 became a parent.  Because 0:4 is
+   * not visible, not signals are emitted.
+   */
+  set_path_visibility (fixture, "0:4:2", TRUE);
+  set_path_visibility (fixture, "0:4:4", TRUE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, "0:4", 2);
+}
+
+static void
+filled_hide_child_levels_root_expanded (FilterTest    *fixture,
+                                        gconstpointer  user_data)
+{
+  GtkTreePath *path;
+
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
+  gtk_tree_path_free (path);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
+  set_path_visibility (fixture, "0:2", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
+  set_path_visibility (fixture, "0:4", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "0:4:3", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "0:4:0", FALSE);
+  set_path_visibility (fixture, "0:4:1", FALSE);
+  set_path_visibility (fixture, "0:4:2", FALSE);
+  set_path_visibility (fixture, "0:4:4", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
+  set_path_visibility (fixture, "0:4", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, "0:3", 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
+  set_path_visibility (fixture, "0:2", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0:4", 0);
+
+  /* has-child-toggled for 0:4 is required.  */
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
+  set_path_visibility (fixture, "0:4:2", TRUE);
+  set_path_visibility (fixture, "0:4:4", TRUE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, "0:4", 2);
+}
+
+
+static void
+filled_vroot_hide_root_level (FilterTest    *fixture,
+                              gconstpointer  user_data)
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  /* These changes do not affect the filter's root level */
+  set_path_visibility (fixture, "0", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
+
+  set_path_visibility (fixture, "4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
+
+  /* Even though we set the virtual root parent node to FALSE,
+   * the virtual root contents remain.
+   */
+  set_path_visibility (fixture, "2", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
+
+  /* No change */
+  set_path_visibility (fixture, "1", FALSE);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
+
+  set_path_visibility (fixture, "3", FALSE);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
+
+  check_filter_model_with_root (fixture, path);
+
+  /* Show some */
+  set_path_visibility (fixture, "2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
+
+  set_path_visibility (fixture, "1", TRUE);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
+
+  set_path_visibility (fixture, "3", TRUE);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH);
+
+  check_filter_model_with_root (fixture, path);
+
+  /* Now test changes in the virtual root level */
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
+  set_path_visibility (fixture, "2:2", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
+  set_path_visibility (fixture, "2:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "1:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
+  set_path_visibility (fixture, "2:4", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+
+  set_path_visibility (fixture, "2", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  set_path_visibility (fixture, "2:0", FALSE);
+  set_path_visibility (fixture, "2:1", FALSE);
+  set_path_visibility (fixture, "2:2", FALSE);
+  set_path_visibility (fixture, "2:3", FALSE);
+  set_path_visibility (fixture, "2:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  set_path_visibility (fixture, "2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  set_path_visibility (fixture, "1:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2:4", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  set_path_visibility (fixture, "2:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  set_path_visibility (fixture, "2", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  set_path_visibility (fixture, "2:0", TRUE);
+  set_path_visibility (fixture, "2:1", TRUE);
+  set_path_visibility (fixture, "2:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
+}
+
+static void
+filled_vroot_hide_child_levels (FilterTest    *fixture,
+                                gconstpointer  user_data)
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  set_path_visibility (fixture, "2:0:2", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
+
+  set_path_visibility (fixture, "2:0:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "2:0:4:3", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "2:0:4:0", FALSE);
+  set_path_visibility (fixture, "2:0:4:1", FALSE);
+  set_path_visibility (fixture, "2:0:4:2", FALSE);
+  set_path_visibility (fixture, "2:0:4:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
+  set_path_visibility (fixture, "2:0:4", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, "0:3", 0);
+
+  set_path_visibility (fixture, "2:0:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0:4", 0);
+
+  /* Once 0:4:0 got inserted, 0:4 became a parent. However, 0:4 is not
+   * visible, so no signal should be emitted.
+   */
+  set_path_visibility (fixture, "2:0:4:2", TRUE);
+  set_path_visibility (fixture, "2:0:4:4", TRUE);
+  check_level_length (fixture->filter, "0:4", 2);
+  signal_monitor_assert_is_empty (fixture->monitor);
+}
+
+static void
+filled_vroot_hide_child_levels_root_expanded (FilterTest    *fixture,
+                                              gconstpointer  user_data)
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+  GtkTreePath *tmp_path;
+
+  tmp_path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), tmp_path, FALSE);
+  gtk_tree_path_free (tmp_path);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
+  set_path_visibility (fixture, "2:0:2", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
+  set_path_visibility (fixture, "2:0:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "2:0:4:3", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  set_path_visibility (fixture, "2:0:4:0", FALSE);
+  set_path_visibility (fixture, "2:0:4:1", FALSE);
+  set_path_visibility (fixture, "2:0:4:2", FALSE);
+  set_path_visibility (fixture, "2:0:4:4", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
+
+  /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
+  set_path_visibility (fixture, "2:0:4", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, "0:3", 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
+  set_path_visibility (fixture, "2:0:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "0:4", 0);
+
+  /* Once 0:4:0 got inserted, 0:4 became a parent */
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
+  set_path_visibility (fixture, "2:0:4:2", TRUE);
+  set_path_visibility (fixture, "2:0:4:4", TRUE);
+  check_level_length (fixture->filter, "0:4", 2);
+  signal_monitor_assert_is_empty (fixture->monitor);
+}
+
+static void
+empty_show_nodes (FilterTest    *fixture,
+                  gconstpointer  user_data)
+{
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "3", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 0);
+
+  set_path_visibility (fixture, "3:2:2", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "3:2", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 1);
+  check_level_length (fixture->filter, "0:0:0", 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  set_path_visibility (fixture, "3", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "3:2:1", TRUE);
+  set_path_visibility (fixture, "3", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 2);
+  check_level_length (fixture->filter, "0:0:0", 0);
+}
+
+static void
+empty_show_multiple_nodes (FilterTest    *fixture,
+                           gconstpointer  user_data)
+{
+  GtkTreeIter iter;
+  GtkTreePath *changed_path;
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
+  /* We simulate a change in visible func condition with this.  The
+   * visibility state of multiple nodes changes at once, we emit row-changed
+   * for these nodes (and others) after that.
+   */
+  filter_test_block_signals (fixture);
+  set_path_visibility (fixture, "3", TRUE);
+  set_path_visibility (fixture, "4", TRUE);
+  filter_test_unblock_signals (fixture);
+
+  changed_path = gtk_tree_path_new ();
+  gtk_tree_path_append_index (changed_path, 2);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+                           &iter, changed_path);
+  /* Invisible node - so no signals expected */
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_next (changed_path);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_next (changed_path);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_free (changed_path);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 2);
+  check_level_length (fixture->filter, "0", 0);
+
+  set_path_visibility (fixture, "3:2:2", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 2);
+  check_level_length (fixture->filter, "0", 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "3:2", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 2);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 1);
+  check_level_length (fixture->filter, "0:0:0", 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  set_path_visibility (fixture, "3", FALSE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "3:2:1", TRUE);
+  set_path_visibility (fixture, "3", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 2);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 2);
+  check_level_length (fixture->filter, "0:0:0", 0);
+}
+
+static void
+empty_vroot_show_nodes (FilterTest    *fixture,
+                        gconstpointer  user_data)
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  set_path_visibility (fixture, "2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  set_path_visibility (fixture, "2:2:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 0);
+
+  set_path_visibility (fixture, "3", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  set_path_visibility (fixture, "2:2", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2:2:1", TRUE);
+  set_path_visibility (fixture, "2:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 2);
+  check_level_length (fixture->filter, "0:1", 0);
+}
+
+static void
+empty_vroot_show_multiple_nodes (FilterTest    *fixture,
+                                 gconstpointer  user_data)
+{
+  GtkTreeIter iter;
+  GtkTreePath *changed_path;
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* We simulate a change in visible func condition with this.  The
+   * visibility state of multiple nodes changes at once, we emit row-changed
+   * for these nodes (and others) after that.
+   */
+  filter_test_block_signals (fixture);
+  set_path_visibility (fixture, "2", TRUE);
+  set_path_visibility (fixture, "3", TRUE);
+  filter_test_unblock_signals (fixture);
+
+  changed_path = gtk_tree_path_new ();
+  gtk_tree_path_append_index (changed_path, 1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+                           &iter, changed_path);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_next (changed_path);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_next (changed_path);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_next (changed_path);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_free (changed_path);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  set_path_visibility (fixture, "2:2:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
+  /* Again, we simulate a call to refilter */
+  filter_test_block_signals (fixture);
+  set_path_visibility (fixture, "2:2", TRUE);
+  set_path_visibility (fixture, "2:3", TRUE);
+  filter_test_unblock_signals (fixture);
+
+  changed_path = gtk_tree_path_new ();
+  gtk_tree_path_append_index (changed_path, 2);
+  gtk_tree_path_append_index (changed_path, 1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+                           &iter, changed_path);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_next (changed_path);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_next (changed_path);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_next (changed_path);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
+                              changed_path, &iter);
+
+  gtk_tree_path_free (changed_path);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 2);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 0);
+
+  set_path_visibility (fixture, "3", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 2);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+  set_path_visibility (fixture, "2:2", FALSE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2:2:1", TRUE);
+  set_path_visibility (fixture, "2:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 2);
+  check_level_length (fixture->filter, "0", 2);
+  check_level_length (fixture->filter, "0:1", 0);
+}
+
+
+static void
+unfiltered_hide_single (FilterTest    *fixture,
+                        gconstpointer  user_data)
+
+{
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  set_path_visibility (fixture, "2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+
+  /* The view only shows the root level, so we only expect signals
+   * for the root level.
+   */
+  filter_test_append_refilter_signals (fixture, 1);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_hide_single_root_expanded (FilterTest    *fixture,
+                                      gconstpointer  user_data)
+
+{
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  set_path_visibility (fixture, "2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals (fixture, 2);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_hide_single_child (FilterTest    *fixture,
+                              gconstpointer  user_data)
+
+{
+  /* This row is not shown, so its signal is not propagated */
+  set_path_visibility (fixture, "2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+
+  /* The view only shows the root level, so we only expect signals
+   * for the root level.
+   */
+  filter_test_append_refilter_signals (fixture, 0);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_hide_single_child_root_expanded (FilterTest    *fixture,
+                                            gconstpointer  user_data)
+
+{
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals (fixture, 2);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_hide_single_multi_level (FilterTest    *fixture,
+                                    gconstpointer  user_data)
+
+{
+  /* This row is not shown, so its signal is not propagated */
+  set_path_visibility (fixture, "2:2:2", FALSE);
+
+  /* This row is not shown, so its signal is not propagated */
+  set_path_visibility (fixture, "2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+
+  /* The view only shows the root level, so we only expect signals
+   * for the root level.
+   */
+  filter_test_append_refilter_signals (fixture, 1);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+
+  set_path_visibility (fixture, "2:2", TRUE);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_hide_single_multi_level_root_expanded (FilterTest    *fixture,
+                                                  gconstpointer  user_data)
+
+{
+  /* This row is not shown, so its signal is not propagated */
+  set_path_visibility (fixture, "2:2:2", FALSE);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals (fixture, 2);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2", TRUE);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
+}
+
+
+
+static void
+unfiltered_vroot_hide_single (FilterTest    *fixture,
+                              gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  set_path_visibility (fixture, "2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+
+  /* The view only shows the root level, so we only expect signals
+   * for the root level.  (Though for the depth argument, we have to
+   * take the virtual root into account).
+   */
+  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_vroot_hide_single_child (FilterTest    *fixture,
+                                    gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  /* Not visible, so no signal will be received. */
+  set_path_visibility (fixture, "2:2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+
+  /* The view only shows the root level, so we only expect signals
+   * for the root level.  (Though for the depth argument, we have to
+   * take the virtual root into account).
+   */
+  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_vroot_hide_single_child_root_expanded (FilterTest    *fixture,
+                                                  gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_vroot_hide_single_multi_level (FilterTest    *fixture,
+                                          gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  /* This row is not shown, so its signal is not propagated */
+  set_path_visibility (fixture, "2:2:2:2", FALSE);
+
+  /* Not shown, so no signal */
+  set_path_visibility (fixture, "2:2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+
+  /* We only expect signals for the root level.  The depth is 2
+   * because we have to take the virtual root into account.
+   */
+  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+
+  /* Not shown, so no signal */
+  set_path_visibility (fixture, "2:2:2", TRUE);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_vroot_hide_single_multi_level_root_expanded (FilterTest    *fixture,
+                                                        gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  /* This row is not shown, so its signal is not propagated */
+  set_path_visibility (fixture, "2:2:2:2", FALSE);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2:2", FALSE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2:2", TRUE);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
+}
+
+static void
+unfiltered_show_single (FilterTest    *fixture,
+                        gconstpointer  user_data)
+
+{
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  set_path_visibility (fixture, "2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+
+  /* We only expect signals for the root level */
+  filter_test_append_refilter_signals (fixture, 1);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 1);
+}
+
+static void
+unfiltered_show_single_child (FilterTest    *fixture,
+                              gconstpointer  user_data)
+
+{
+  set_path_visibility (fixture, "2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+
+  /* We only expect signals for the root level */
+  filter_test_append_refilter_signals (fixture, 1);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* From here we are filtered, "2" in the real model is "0" in the filter
+   * model.
+   */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2", TRUE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+}
+
+static void
+unfiltered_show_single_child_root_expanded (FilterTest    *fixture,
+                                            gconstpointer  user_data)
+
+{
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals (fixture, 2);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* From here we are filtered, "2" in the real model is "0" in the filter
+   * model.
+   */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2", TRUE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+}
+
+static void
+unfiltered_show_single_multi_level (FilterTest    *fixture,
+                                    gconstpointer  user_data)
+
+{
+  /* The view is not showing these rows (collapsed state), so it is not
+   * referenced.  The signal should not go through.
+   */
+  set_path_visibility (fixture, "2:2:2", TRUE);
+  set_path_visibility (fixture, "2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+
+  /* We only expect signals for the first level */
+  filter_test_append_refilter_signals (fixture, 1);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* From here we are filtered, "2" in the real model is "0" in the filter
+   * model.
+   */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 1);
+}
+
+static void
+unfiltered_show_single_multi_level_root_expanded (FilterTest    *fixture,
+                                                  gconstpointer  user_data)
+
+{
+  /* The view is not showing this row (collapsed state), so it is not
+   * referenced.  The signal should not go through.
+   */
+  set_path_visibility (fixture, "2:2:2", TRUE);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals (fixture, 2);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* From here we are filtered, "2" in the real model is "0" in the filter
+   * model.
+   */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2", TRUE);
+  check_filter_model (fixture);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 1);
+}
+
+static void
+unfiltered_vroot_show_single (FilterTest    *fixture,
+                              gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  set_path_visibility (fixture, "2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+
+  /* The view only shows the root level, so the filter model only has
+   * the first two levels cached.
+   */
+  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 1);
+}
+
+static void
+unfiltered_vroot_show_single_child (FilterTest    *fixture,
+                                    gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  set_path_visibility (fixture, "2:2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+
+  /* The view only shows the root level, so the filter model only has
+   * the first two levels cached.
+   */
+  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* From here we are filtered, "2" in the real model is "0" in the filter
+   * model.
+   */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2:2", TRUE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+}
+
+static void
+unfiltered_vroot_show_single_child_root_expanded (FilterTest    *fixture,
+                                                  gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* From here we are filtered, "2" in the real model is "0" in the filter
+   * model.
+   */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2:2", TRUE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+}
+
+
+static void
+unfiltered_vroot_show_single_multi_level (FilterTest    *fixture,
+                                          gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  /* The view is not showing this row (collapsed state), so it is not
+   * referenced.  The signal should not go through.
+   */
+  set_path_visibility (fixture, "2:2:2:2", TRUE);
+
+  set_path_visibility (fixture, "2:2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+
+  /* We only expect signals for the root level */
+  filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* From here we are filtered, "2" in the real model is "0" in the filter
+   * model.
+   */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 1);
+}
+
+static void
+unfiltered_vroot_show_single_multi_level_root_expanded (FilterTest    *fixture,
+                                                        gconstpointer  user_data)
+
+{
+  GtkTreePath *path = (GtkTreePath *)user_data;
+
+  /* The view is not showing this row (collapsed state), so it is not
+   * referenced.  The signal should not go through.
+   */
+  set_path_visibility (fixture, "2:2:2:2", TRUE);
+
+  signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
+  set_path_visibility (fixture, "2:2:2", TRUE);
+
+  signal_monitor_assert_is_empty (fixture->monitor);
+  check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+  check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+
+  filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
+  filter_test_enable_filter (fixture);
+
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 0);
+
+  /* From here we are filtered, "2" in the real model is "0" in the filter
+   * model.
+   */
+  signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "2:2", TRUE);
+  check_filter_model_with_root (fixture, path);
+  check_level_length (fixture->filter, NULL, 1);
+  check_level_length (fixture->filter, "0", 1);
+  check_level_length (fixture->filter, "0:0", 1);
+}
+
+static void
+unfiltered_rows_reordered_root_level (FilterTest    *fixture,
+                                      gconstpointer  user_data)
+{
+  int order0[] = { 1, 2, 3, 4, 0 };
+  int order1[] = { 0, 2, 1, 3, 4 };
+  int order2[] = { 4, 0, 1, 2, 3 };
+  GtkTreeIter iter0, iter1, iter2, iter3, iter4;
+  GtkTreePath *path;
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter0, "0");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter1, "1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter2, "2");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter3, "3");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter4, "4");
+
+  path = gtk_tree_path_new ();
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order0, 5);
+  gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order1, 5);
+  gtk_tree_store_move_after (fixture->store, &iter2, &iter3);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order2, 5);
+  gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+unfiltered_rows_reordered_child_level (FilterTest    *fixture,
+                                       gconstpointer  user_data)
+{
+  int order0[] = { 1, 2, 3, 4, 0 };
+  int order1[] = { 0, 2, 1, 3, 4 };
+  int order2[] = { 4, 0, 1, 2, 3 };
+  GtkTreeIter iter0, iter1, iter2, iter3, iter4;
+  GtkTreePath *path;
+
+  /* Expand row 0 */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter0, "0:0");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter1, "0:1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter2, "0:2");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter3, "0:3");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter4, "0:4");
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order0, 5);
+  gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order1, 5);
+  gtk_tree_store_move_after (fixture->store, &iter2, &iter3);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order2, 5);
+  gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+filtered_rows_reordered_root_level_first_hidden (FilterTest    *fixture,
+                                                 gconstpointer  user_data)
+{
+  int order0[] = { 1, 2, 3, 0 };
+  int order1[] = { 0, 2, 1, 3 };
+  int order2[] = { 3, 0, 1, 2 };
+  GtkTreeIter iter1, iter2, iter3, iter4;
+  GtkTreePath *path;
+
+  /* Hide middle path */
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0");
+  set_path_visibility (fixture, "0", FALSE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter1, "1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter2, "2");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter3, "3");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter4, "4");
+
+  path = gtk_tree_path_new ();
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order0, 4);
+  gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order1, 4);
+  gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order2, 4);
+  gtk_tree_store_move_before (fixture->store, &iter1, &iter2);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+filtered_rows_reordered_root_level_middle_hidden (FilterTest    *fixture,
+                                                  gconstpointer  user_data)
+{
+  int order0[] = { 1, 2, 3, 0 };
+  int order1[] = { 0, 2, 1, 3 };
+  int order2[] = { 3, 0, 1, 2 };
+  GtkTreeIter iter0, iter1, iter3, iter4;
+  GtkTreePath *path;
+
+  /* Hide middle path */
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "2");
+  set_path_visibility (fixture, "2", FALSE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter0, "0");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter1, "1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter3, "3");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter4, "4");
+
+  path = gtk_tree_path_new ();
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order0, 4);
+  gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order1, 4);
+  gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order2, 4);
+  gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+filtered_rows_reordered_child_level_first_hidden (FilterTest    *fixture,
+                                                  gconstpointer  user_data)
+{
+  int order0[] = { 1, 2, 3, 0 };
+  int order1[] = { 0, 2, 1, 3 };
+  int order2[] = { 3, 0, 1, 2 };
+  GtkTreeIter iter1, iter2, iter3, iter4;
+  GtkTreePath *path;
+
+  /* Expand row 0 */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, TRUE);
+
+  /* Hide middle path */
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:0");
+  set_path_visibility (fixture, "0:0", FALSE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter1, "0:1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter2, "0:2");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter3, "0:3");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter4, "0:4");
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order0, 4);
+  gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order1, 4);
+  gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order2, 4);
+  gtk_tree_store_move_before (fixture->store, &iter1, &iter2);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+filtered_rows_reordered_child_level_middle_hidden (FilterTest    *fixture,
+                                                   gconstpointer  user_data)
+{
+  int order0[] = { 1, 2, 3, 0 };
+  int order1[] = { 0, 2, 1, 3 };
+  int order2[] = { 3, 0, 1, 2 };
+  GtkTreeIter iter0, iter1, iter3, iter4;
+  GtkTreePath *path;
+
+  /* Expand row 0 */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
+
+  /* Hide middle path */
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:2");
+  set_path_visibility (fixture, "0:2", FALSE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter0, "0:0");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter1, "0:1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter3, "0:3");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter4, "0:4");
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order0, 4);
+  gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order1, 4);
+  gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order2, 4);
+  gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+filtered_rows_reordered_child_level_4_hidden (FilterTest    *fixture,
+                                              gconstpointer  user_data)
+{
+  int order0[] = { 0 };
+  GtkTreeIter iter1, iter4;
+  GtkTreePath *path;
+
+  /* Expand row 0 */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
+
+  /* Hide last 4 paths */
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:4");
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:3");
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:2");
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:0");
+  set_path_visibility (fixture, "0:4", FALSE);
+  set_path_visibility (fixture, "0:3", FALSE);
+  set_path_visibility (fixture, "0:2", FALSE);
+  set_path_visibility (fixture, "0:0", FALSE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter1, "0:1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter4, "0:4");
+
+  signal_monitor_append_signal_reordered (fixture->monitor,
+                                          ROWS_REORDERED,
+                                          path, order0, 1);
+  gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+filtered_rows_reordered_child_level_all_hidden (FilterTest    *fixture,
+                                                gconstpointer  user_data)
+{
+  GtkTreeIter iter1, iter4;
+  GtkTreePath *path;
+
+  /* Expand row 0 */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
+  gtk_tree_path_free (path);
+
+  /* Hide last 4 paths */
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:4");
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:3");
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:2");
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:1");
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_DELETED, "0:0");
+  signal_monitor_append_signal (fixture->monitor,
+                                ROW_HAS_CHILD_TOGGLED, "0");
+  set_path_visibility (fixture, "0:4", FALSE);
+  set_path_visibility (fixture, "0:3", FALSE);
+  set_path_visibility (fixture, "0:2", FALSE);
+  set_path_visibility (fixture, "0:1", FALSE);
+  set_path_visibility (fixture, "0:0", FALSE);
+  signal_monitor_assert_is_empty (fixture->monitor);
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter1, "0:1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
+                                       &iter4, "0:4");
+
+  gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
+  signal_monitor_assert_is_empty (fixture->monitor);
+}
+
+static void
+insert_before (void)
+{
+  GtkTreeStore *store;
+  GtkTreeModel *filter;
+  GtkWidget *tree_view;
+  SignalMonitor *monitor;
+  GtkTreeIter iter;
+  GtkTreeIter last_iter;
+  GtkTreePath *path;
+
+  /* This tests two aspects of the row-inserted handling:
+   *   1) If the newly inserted node was already handled by building
+   *      the root level, don't handle it a second time.
+   *   2) Offsets of existing nodes must be updated when a new
+   *      node is inserted.
+   */
+
+  store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
+                                            1);
+
+  tree_view = gtk_tree_view_new_with_model (filter);
+  monitor = signal_monitor_new (filter);
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 0);
+
+  /* Insert 0 */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
+  gtk_tree_path_free (path);
+
+  gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
+                                     0, "Foo", 1, TRUE, -1);
+
+  signal_monitor_assert_is_empty (monitor);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
+
+  /* Insert 1 */
+  path = gtk_tree_path_new_from_indices (1, -1);
+  signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
+  gtk_tree_path_free (path);
+
+  gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
+                                     0, "Foo", 1, TRUE, -1);
+  last_iter = iter;
+
+  signal_monitor_assert_is_empty (monitor);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
+
+  /* Insert on 1 again -- invisible */
+  gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
+                                     0, "Foo", 1, FALSE, -1);
+
+  signal_monitor_assert_is_empty (monitor);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
+
+  /* Insert on 1 again -- visible */
+  path = gtk_tree_path_new_from_indices (1, -1);
+  signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
+  gtk_tree_path_free (path);
+
+  gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
+                                     0, "Foo", 1, TRUE, -1);
+
+  signal_monitor_assert_is_empty (monitor);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 3);
+
+  /* Modify the iter that should be at the last position and check the
+   * signal we get.
+   */
+  path = gtk_tree_path_new_from_indices (2, -1);
+  signal_monitor_append_signal_path (monitor, ROW_CHANGED, path);
+  gtk_tree_path_free (path);
+
+  gtk_tree_store_set (store, &last_iter, 0, "Foo changed", -1);
+
+  signal_monitor_assert_is_empty (monitor);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 3);
+
+  g_object_unref (filter);
+  g_object_unref (store);
+  gtk_widget_destroy (tree_view);
+}
+
+static void
+insert_child (void)
+{
+  GtkTreeStore *store;
+  GtkTreeModel *filter;
+  GtkWidget *tree_view;
+  SignalMonitor *monitor;
+  GtkTreeIter parent, iter;
+  GtkTreePath *path;
+
+  store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+
+  gtk_tree_store_insert_with_values (store, &parent, NULL, 0,
+                                     0, "Parent", 1, TRUE, -1);
+
+
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
+                                            1);
+
+  tree_view = gtk_tree_view_new_with_model (filter);
+  monitor = signal_monitor_new (filter);
+
+  /* Insert child -- invisible */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
+  /* The signal is received twice, once a pass through from GtkTreeStore
+   * and one generated by GtkTreeModelFilter.  Not accurate, but cannot
+   * hurt.
+   */
+  signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
+  gtk_tree_path_free (path);
+
+  gtk_tree_store_insert_with_values (store, &iter, &parent, 1,
+                                     0, "Child", 1, FALSE, -1);
+
+  signal_monitor_assert_is_empty (monitor);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
+
+  /* Insert child */
+  path = gtk_tree_path_new_from_indices (0, 0, -1);
+  gtk_tree_path_up (path); /* 0 */
+  signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
+  gtk_tree_path_free (path);
+
+  gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
+                                     0, "Child", 1, TRUE, -1);
+
+  signal_monitor_assert_is_empty (monitor);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
+
+  /* Insert child -- invisible */
+  gtk_tree_store_insert_with_values (store, &iter, &parent, 1,
+                                     0, "Child", 1, FALSE, -1);
+
+  signal_monitor_assert_is_empty (monitor);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
+
+  g_object_unref (filter);
+  g_object_unref (store);
+  gtk_widget_destroy (tree_view);
+}
+
+
+
+static void
+remove_node (void)
+{
+  GtkTreeIter iter, iter1, iter2, iter3;
+  GtkListStore *list;
+  GtkTreeModel *filter;
+  GtkWidget *view G_GNUC_UNUSED;
+
+  list = gtk_list_store_new (1, G_TYPE_INT);
+  gtk_list_store_insert_with_values (list, &iter1, 0, 0, 1, -1);
+  gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
+  gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
+  gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
+  gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
+  gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
+  gtk_list_store_insert_with_values (list, &iter2, 6, 0, 7, -1);
+  gtk_list_store_insert_with_values (list, &iter3, 7, 0, 8, -1);
+
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
+  view = gtk_tree_view_new_with_model (filter);
+
+  gtk_list_store_remove (list, &iter1);
+  gtk_list_store_remove (list, &iter3);
+  gtk_list_store_remove (list, &iter2);
+
+  gtk_widget_destroy (view);
+  g_object_unref (filter);
+  g_object_unref (list);
+}
+
+static void
+remove_node_vroot (void)
+{
+  GtkTreeIter parent, root;
+  GtkTreeIter iter, iter1, iter2, iter3;
+  GtkTreeStore *tree;
+  GtkTreeModel *filter;
+  GtkTreePath *path;
+  GtkWidget *view G_GNUC_UNUSED;
+
+  tree = gtk_tree_store_new (1, G_TYPE_INT);
+  gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
+  gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
+
+  gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
+  gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
+  gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
+
+  path = gtk_tree_path_new_from_indices (0, 0, -1);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
+  gtk_tree_path_free (path);
+
+  view = gtk_tree_view_new_with_model (filter);
+
+  gtk_tree_store_remove (tree, &iter1);
+  gtk_tree_store_remove (tree, &iter3);
+  gtk_tree_store_remove (tree, &iter2);
+
+  gtk_widget_destroy (view);
+  g_object_unref (filter);
+  g_object_unref (tree);
+}
+
+static void
+remove_vroot_ancestor (void)
+{
+  GtkTreeIter parent, root;
+  GtkTreeIter iter, iter1, iter2, iter3;
+  GtkTreeStore *tree;
+  GtkTreeModel *filter;
+  GtkTreePath *path;
+  GtkWidget *view G_GNUC_UNUSED;
+
+  tree = gtk_tree_store_new (1, G_TYPE_INT);
+  gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
+  gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
+
+  gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
+  gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
+  gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
+
+  path = gtk_tree_path_new_from_indices (0, 0, -1);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
+  gtk_tree_path_free (path);
+
+  view = gtk_tree_view_new_with_model (filter);
+
+  gtk_tree_store_remove (tree, &parent);
+
+  gtk_widget_destroy (view);
+  g_object_unref (filter);
+  g_object_unref (tree);
+}
+
+static void
+ref_count_single_level (void)
+{
+  GtkTreeIter iter[5];
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[0], NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[1], NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[2], NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[3], NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter[4], NULL);
+
+  assert_root_level_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &iter[0], 2);
+  assert_node_ref_count (ref_model, &iter[1], 1);
+  assert_node_ref_count (ref_model, &iter[2], 1);
+  assert_node_ref_count (ref_model, &iter[3], 1);
+  assert_node_ref_count (ref_model, &iter[4], 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_node_ref_count (ref_model, &iter[0], 1);
+  assert_node_ref_count (ref_model, &iter[1], 0);
+  assert_node_ref_count (ref_model, &iter[2], 0);
+  assert_node_ref_count (ref_model, &iter[3], 0);
+  assert_node_ref_count (ref_model, &iter[4], 0);
+
+  g_object_unref (filter_model);
+
+  assert_node_ref_count (ref_model, &iter[0], 0);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_two_levels (void)
+{
+  GtkTreeIter parent1, parent2, iter, iter_first;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_first, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  /* This is quite confusing:
+   *  - node 0 has a ref count of 2 because it is referenced as the
+   *    first node in a level and by the tree view.
+   *  - node 1 has a ref count of 2 because it is referenced by its
+   *    child level and by the tree view.
+   */
+  assert_root_level_referenced (ref_model, 2);
+  assert_node_ref_count (ref_model, &iter_first, 1);
+  assert_node_ref_count (ref_model, &iter, 0);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_first, 2);
+  assert_node_ref_count (ref_model, &iter, 1);
+
+  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
+
+  /* The child level is not destroyed because its parent is visible */
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_first, 1);
+  assert_node_ref_count (ref_model, &iter, 0);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_first, 1);
+  assert_node_ref_count (ref_model, &iter, 0);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_node_ref_count (ref_model, &iter_first, 1);
+  assert_node_ref_count (ref_model, &iter, 0);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  /* The root level and first level remain cached, only the references on the
+   * first nodes of these levels are kept.
+   */
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_first, 1);
+  assert_node_ref_count (ref_model, &iter, 0);
+
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_three_levels (void)
+{
+  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
+  GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   *   + parent1
+   *     + iter_parent1
+   *   + parent2
+   *     + iter_parent2_first
+   *     + iter_parent2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  /* This is quite confusing:
+   *  - node 0 has a ref count of 2 because it is referenced as the
+   *    first node in a level and by the tree view.
+   *  - node 1 has a ref count of 2 because it is referenced by its
+   *    child level and by the tree view.
+   */
+  assert_root_level_referenced (ref_model, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_unreferenced (ref_model, &parent2);
+
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 2);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_path_append_index (path, 1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_path_up (path);
+  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_widget_destroy (tree_view);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  /* The root level and first level remain cached, only the references on the
+   * first nodes of these levels are kept.  Grandparent2 is the parent
+   * of the first level with parent1, so grandparent2 keeps a reference
+   * as well.
+   */
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_delete_row (void)
+{
+  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
+  GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   *   + parent1
+   *     + iter_parent1
+   *   + parent2
+   *     + iter_parent2_first
+   *     + iter_parent2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_root_level_referenced (ref_model, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_unreferenced (ref_model, &parent2);
+
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 2);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter_parent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 2);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent2, 3);
+  assert_level_referenced (ref_model, 2, &parent2);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+
+  gtk_widget_destroy (tree_view);
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+
+  g_object_unref (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_filter_row_length_1 (void)
+{
+  GtkTreeIter level1_1;
+  GtkTreeIter level2_1;
+  GtkTreeIter level3_1;
+  GtkTreeIter level4_1;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+
+  /* + level1_1
+   *   + level2_1
+   *     + level3_1
+   *       + level4_1
+   *
+   * Node level1_1 is expanded.  This makes that levels 1 and 2 are
+   * visible.  Level 3 is cached because its parent is visible.  Level 4
+   * is not cached.
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 3);
+  assert_node_ref_count (ref_model, &level3_1, 1);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 3);
+  assert_node_ref_count (ref_model, &level3_1, 1);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  /* level3_1 has a visible parent, so the node is kept in the cache. */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 3);
+  assert_node_ref_count (ref_model, &level3_1, 1);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  /* level2_1 has a visible parent, so is kept in the cache.  However,
+   * the external reference should be released.
+   */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  gtk_widget_destroy (tree_view);
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+
+  g_object_unref (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 0);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_filter_row_length_1_remove_in_root_level (void)
+{
+  GtkTreeIter level1_1;
+  GtkTreeIter level2_1;
+  GtkTreeIter level3_1;
+  GtkTreeIter level4_1;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+
+  /* + level1_1
+   *   + level2_1
+   *     + level3_1
+   *       + level4_1
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 3);
+  assert_node_ref_count (ref_model, &level3_1, 3);
+  assert_node_ref_count (ref_model, &level4_1, 2);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  gtk_widget_destroy (tree_view);
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  g_object_unref (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 0);
+  assert_node_ref_count (ref_model, &level2_1, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_filter_row_length_1_remove_in_child_level (void)
+{
+  GtkTreeIter level1_1;
+  GtkTreeIter level2_1;
+  GtkTreeIter level3_1;
+  GtkTreeIter level4_1;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+
+  /* + level1_1
+   *   + level2_1
+   *     + level3_1
+   *       + level4_1
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 3);
+  assert_node_ref_count (ref_model, &level3_1, 3);
+  assert_node_ref_count (ref_model, &level4_1, 2);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 3);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  gtk_widget_destroy (tree_view);
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  g_object_unref (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 0);
+  assert_node_ref_count (ref_model, &level2_1, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_filter_row_length_gt_1 (void)
+{
+  GtkTreeIter level1_1, level1_2;
+  GtkTreeIter level2_1, level2_2;
+  GtkTreeIter level3_1, level3_2;
+  GtkTreeIter level4_1, level4_2;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+
+  /* + level1_1
+   * + level1_2
+   *   + level2_1
+   *   + level2_2
+   *     + level3_1
+   *     + level3_2
+   *       + level4_1
+   *       + level4_2
+   *
+   * Node level1_2 is expanded.  This makes that levels 1 and 2 are
+   * visible.  Level 3 is cached because its parent is visible.  Level 4
+   * is not cached.
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_2, &level1_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_2, &level2_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_2, &level3_2);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_2, 0, TRUE, -1);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 2);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level2_2, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 2);
+  assert_node_ref_count (ref_model, &level2_1, 2);
+  assert_node_ref_count (ref_model, &level2_2, 2);
+  assert_node_ref_count (ref_model, &level3_1, 1);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 2);
+  assert_node_ref_count (ref_model, &level2_1, 2);
+  assert_node_ref_count (ref_model, &level2_2, 2);
+  assert_node_ref_count (ref_model, &level3_1, 1);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 2);
+  assert_node_ref_count (ref_model, &level2_1, 2);
+  assert_node_ref_count (ref_model, &level2_2, 2);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level3_2, 1);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 2);
+  assert_node_ref_count (ref_model, &level2_1, 2);
+  assert_node_ref_count (ref_model, &level2_2, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 0);
+  assert_node_ref_count (ref_model, &level2_1, 0);
+  assert_node_ref_count (ref_model, &level2_2, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  gtk_widget_destroy (tree_view);
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &level1_1, 1);
+
+  g_object_unref (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 0);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_filter_row_length_gt_1_visible_children (void)
+{
+  GtkTreeIter level1_1, level1_2;
+  GtkTreeIter level2_1, level2_2;
+  GtkTreeIter level3_1, level3_2;
+  GtkTreeIter level4_1, level4_2;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+
+  /* + level1_1
+   * + level1_2
+   *   + level2_1
+   *   + level2_2
+   *     + level3_1
+   *     + level3_2
+   *       + level4_1
+   *       + level4_2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level1_2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_1, &level1_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level2_2, &level1_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_1, &level2_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level3_2, &level2_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_1, &level3_2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &level4_2, &level3_2);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level1_2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level3_2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level4_2, 0, TRUE, -1);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 2);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level2_2, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 2);
+  assert_node_ref_count (ref_model, &level2_1, 2);
+  assert_node_ref_count (ref_model, &level2_2, 2);
+  assert_node_ref_count (ref_model, &level3_1, 2);
+  assert_node_ref_count (ref_model, &level3_2, 2);
+  assert_node_ref_count (ref_model, &level4_1, 2);
+  assert_node_ref_count (ref_model, &level4_2, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &level2_2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &level1_1, 2);
+  assert_node_ref_count (ref_model, &level1_2, 2);
+  assert_node_ref_count (ref_model, &level2_1, 2);
+  assert_node_ref_count (ref_model, &level2_2, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  gtk_widget_destroy (tree_view);
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  assert_node_ref_count (ref_model, &level1_1, 1);
+  assert_node_ref_count (ref_model, &level1_2, 1);
+  assert_node_ref_count (ref_model, &level2_1, 1);
+  assert_node_ref_count (ref_model, &level2_2, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  g_object_unref (filter_model);
+
+  assert_node_ref_count (ref_model, &level1_1, 0);
+  assert_node_ref_count (ref_model, &level1_2, 0);
+  assert_node_ref_count (ref_model, &level2_1, 0);
+  assert_node_ref_count (ref_model, &level2_2, 0);
+  assert_node_ref_count (ref_model, &level3_1, 0);
+  assert_node_ref_count (ref_model, &level3_2, 0);
+  assert_node_ref_count (ref_model, &level4_1, 0);
+  assert_node_ref_count (ref_model, &level4_2, 0);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_cleanup (void)
+{
+  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
+  GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   *   + parent1
+   *     + iter_parent1
+   *   + parent2
+   *     + iter_parent2_first
+   *     + iter_parent2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 2);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 2);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  /* The root level and first level remain cached, only the references on the
+   * first nodes of these levels are kept.  Grandparent2 is the parent
+   * of the first level with parent1, so grandparent2 keeps a reference
+   * as well.
+   */
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_row_ref (void)
+{
+  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
+  GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+  GtkTreePath *path;
+  GtkTreeRowReference *row_ref;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   *   + parent1
+   *     + iter_parent1
+   *   + parent2
+   *     + iter_parent2
+   *     + iter_parent2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
+  row_ref = gtk_tree_row_reference_new (filter_model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 3);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
+  row_ref = gtk_tree_row_reference_new (filter_model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 3);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2_first, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+
+  gtk_widget_destroy (tree_view);
+
+  gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
+
+  /* The root level and first level remain cached, only the references on the
+   * first nodes of these levels are kept.  Grandparent2 is the parent
+   * of the first level with parent1, so grandparent2 keeps a reference
+   * as well.
+   */
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &parent1, 1);
+
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_root_level_insert (void)
+{
+  GtkTreeIter grandparent1, grandparent2, grandparent3;
+  GtkTreeIter new_node;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   * + grandparent3
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
+
+  assert_node_ref_count (ref_model, &new_node, 2);
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_root_level_remove (void)
+{
+  GtkTreeIter grandparent1, grandparent2, grandparent3;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   * + grandparent3
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent1);
+
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
+
+  assert_node_ref_count (ref_model, &grandparent3, 2);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_root_level_remove_filtered (void)
+{
+  GtkTreeIter grandparent1, grandparent2, grandparent3, grandparent4;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  /* + grandparent1
+   * + grandparent2
+   * + grandparent3
+   * + grandparent4
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent4, NULL);
+
+  /* Filter first node */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 2);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent3);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 2);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent4);
+
+  /* Check level length to get root level cached again */
+  check_level_length (GTK_TREE_MODEL_FILTER (filter_model), NULL, 0);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter_model), NULL, 1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_root_level_reordered (void)
+{
+  GtkTreeIter grandparent1, grandparent2, grandparent3;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   * + grandparent3
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  /* gtk_tree_store_move() will emit rows-reordered */
+  gtk_tree_store_move_after (GTK_TREE_STORE (model),
+                             &grandparent1, &grandparent3);
+
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_root_level_reordered_filtered (void)
+{
+  GtkTreeIter grandparent1, grandparent2, grandparent3;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  /* + grandparent1
+   * + grandparent2
+   * + grandparent3
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
+
+  /* Test with 1 node filtered */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, TRUE, -1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  /* Move the invisible node grandparent1 */
+
+  /* gtk_tree_store_move() will emit rows-reordered */
+  gtk_tree_store_move_after (GTK_TREE_STORE (model),
+                             &grandparent1, &grandparent3);
+
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+
+  /* Move the invisible node grandparent1 */
+
+  /* gtk_tree_store_move() will emit rows-reordered */
+  gtk_tree_store_move_before (GTK_TREE_STORE (model),
+                              &grandparent1, &grandparent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  /* Now swap grandparent2 and grandparent3, first reference must transfer */
+  /* gtk_tree_store_swap() will emit rows-reordered */
+  gtk_tree_store_swap (GTK_TREE_STORE (model),
+                       &grandparent2, &grandparent3);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+
+  /* Swap back */
+  gtk_tree_store_swap (GTK_TREE_STORE (model),
+                       &grandparent2, &grandparent3);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+
+  /* Test with two nodes filtered */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 2);
+
+  /* gtk_tree_store_move() will emit rows-reordered */
+  gtk_tree_store_move_before (GTK_TREE_STORE (model),
+                             &grandparent3, &grandparent1);
+
+  assert_node_ref_count (ref_model, &grandparent3, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_root_level_filter (void)
+{
+  GtkTreeIter grandparent1, grandparent2, grandparent3, grandparent4;
+  GtkTreeIter new_node;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  /* + grandparent1
+   * + grandparent2
+   * + grandparent3
+   * + grandparent4
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent4, NULL);
+
+  /* Filter first node */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 2);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 2);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
+
+  assert_node_ref_count (ref_model, &new_node, 0);
+  assert_node_ref_count (ref_model, &grandparent1, 2);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &new_node, 0);
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &new_node);
+  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
+
+  assert_node_ref_count (ref_model, &new_node, 0);
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &new_node, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &new_node, 2);
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &new_node);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_child_level_insert (void)
+{
+  GtkTreeIter grandparent1;
+  GtkTreeIter parent1, parent2, parent3;
+  GtkTreeIter new_node;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   *   + parent1
+   *   + parent2
+   *   + parent3
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &grandparent1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &new_node, 1);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_child_level_remove (void)
+{
+  GtkTreeIter grandparent1;
+  GtkTreeIter parent1, parent2, parent3;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   *   + parent1
+   *   + parent2
+   *   + parent3
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent3, 1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_child_level_remove_filtered (void)
+{
+  GtkTreeIter grandparent1;
+  GtkTreeIter parent1, parent2, parent3, parent4;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  /* + grandparent1
+   *   + parent1
+   *   + parent2
+   *   + parent3
+   *   + parent4
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent4, &grandparent1);
+
+  /* Filter first node */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent1, 0, FALSE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent3, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent4, 0, TRUE, -1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &parent3, 0);
+  assert_node_ref_count (ref_model, &parent4, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent3, 1);
+  assert_node_ref_count (ref_model, &parent4, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent3);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent4, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent4);
+
+  /* Check level length to get level cached again */
+  check_level_length (GTK_TREE_MODEL_FILTER (filter_model), "0", 0);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 1);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent2, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter_model), "0", 1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_child_level_reordered (void)
+{
+  GtkTreeIter grandparent1;
+  GtkTreeIter parent1, parent2, parent3;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   *   + parent1
+   *   + parent2
+   *   + parent3
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  /* gtk_tree_store_move() will emit rows-reordered */
+  gtk_tree_store_move_after (GTK_TREE_STORE (model),
+                             &parent1, &parent3);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &parent3, 0);
+  assert_node_ref_count (ref_model, &parent1, 0);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_child_level_reordered_filtered (void)
+{
+  GtkTreeIter grandparent1;
+  GtkTreeIter parent1, parent2, parent3;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  /* + grandparent1
+   *   + parent1
+   *   + parent2
+   *   + parent3
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
+
+  /* Test with 1 node filtered (parent1) */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent3, 0, TRUE, -1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  /* Move invisible node parent 1 */
+
+  /* gtk_tree_store_move() will emit rows-reordered */
+  gtk_tree_store_move_after (GTK_TREE_STORE (model),
+                             &parent1, &parent3);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &parent3, 0);
+  assert_node_ref_count (ref_model, &parent1, 0);
+
+  /* Move invisible node parent 1 */
+
+  /* gtk_tree_store_move() will emit rows-reordered */
+  gtk_tree_store_move_before (GTK_TREE_STORE (model),
+                              &parent1, &parent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  /* Now swap parent2 and parent2, first reference must transfer */
+  /* gtk_tree_store_swap() will emit rows-reordered */
+  gtk_tree_store_swap (GTK_TREE_STORE (model),
+                       &parent2, &parent3);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent3, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+
+  /* Swap back */
+  gtk_tree_store_swap (GTK_TREE_STORE (model),
+                       &parent2, &parent3);
+
+  assert_node_ref_count (ref_model, &grandparent1, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent1, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &parent3, 0);
+
+  /* Test with two nodes filtered */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent1, 0, FALSE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &parent2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &parent3, 1);
+
+  /* gtk_tree_store_move() will emit rows-reordered */
+  gtk_tree_store_move_before (GTK_TREE_STORE (model),
+                             &parent3, &parent1);
+
+  assert_node_ref_count (ref_model, &parent3, 1);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &parent1, 0);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_transfer_child_level_filter (void)
+{
+  GtkTreeIter root;
+  GtkTreeIter grandparent1, grandparent2, grandparent3, grandparent4;
+  GtkTreeIter new_node;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  /* + root
+   *    + grandparent1
+   *    + grandparent2
+   *    + grandparent3
+   *    + grandparent4
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, &root);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, &root);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, &root);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent4, &root);
+
+  /* Filter first node */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &root, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 1);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent3, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &root);
+
+  assert_node_ref_count (ref_model, &new_node, 0);
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent1, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &new_node, 0);
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &new_node);
+  gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &root);
+
+  assert_node_ref_count (ref_model, &new_node, 0);
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 1);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &new_node, 0, TRUE, -1);
+
+  assert_node_ref_count (ref_model, &new_node, 1);
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 0);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent2, 0, TRUE, -1);
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &new_node);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &grandparent3, 0);
+  assert_node_ref_count (ref_model, &grandparent4, 0);
+
+  gtk_tree_store_set (GTK_TREE_STORE (model), &grandparent4, 0, TRUE, -1);
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+
+static gboolean
+specific_path_dependent_filter_func (GtkTreeModel *model,
+                                     GtkTreeIter  *iter,
+                                     gpointer      data)
+{
+  GtkTreePath *path;
+
+  path = gtk_tree_model_get_path (model, iter);
+  if (gtk_tree_path_get_indices (path)[0] < 4)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+specific_path_dependent_filter (void)
+{
+  int i;
+  GtkTreeIter iter;
+  GtkListStore *list;
+  GtkTreeModel *sort;
+  GtkTreeModel *filter;
+
+  list = gtk_list_store_new (1, G_TYPE_INT);
+  gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
+  gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
+  gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
+  gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
+  gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
+  gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
+  gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
+  gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
+
+  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_path_dependent_filter_func,
+                                          NULL, NULL);
+
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
+                                        GTK_SORT_DESCENDING);
+
+  for (i = 0; i < 4; i++)
+    {
+      if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
+                                         NULL, 1))
+        gtk_list_store_remove (list, &iter);
+
+      if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
+                                         NULL, 2))
+        gtk_list_store_remove (list, &iter);
+    }
+
+  g_object_unref (filter);
+  g_object_unref (sort);
+  g_object_unref (list);
+}
+
+
+static gboolean
+specific_append_after_collapse_visible_func (GtkTreeModel *model,
+                                             GtkTreeIter  *iter,
+                                             gpointer      data)
+{
+  gint number;
+  gboolean hide_negative_numbers;
+
+  gtk_tree_model_get (model, iter, 1, &number, -1);
+  hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
+
+  return (number >= 0 || !hide_negative_numbers);
+}
+
+static void
+specific_append_after_collapse (void)
+{
+  /* This test is based on one of the test cases I found in my
+   * old test cases directory.  I unfortunately do not have a record
+   * from who this test case originated.  -Kris.
+   *
+   * General idea:
+   * - Construct tree.
+   * - Show tree, expand, collapse.
+   * - Add a row.
+   */
+
+  GtkTreeIter iter;
+  GtkTreeIter child_iter;
+  GtkTreeIter child_iter2;
+  GtkTreePath *append_path;
+  GtkTreeStore *store;
+  GtkTreeModel *filter;
+  GtkTreeModel *sort;
+
+  GtkWidget *window;
+  GtkWidget *tree_view;
+
+  store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
+  g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
+                     GINT_TO_POINTER (FALSE));
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_append_after_collapse_visible_func,
+                                          filter, NULL);
+
+  sort = gtk_tree_model_sort_new_with_model (filter);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  tree_view = gtk_tree_view_new_with_model (sort);
+  gtk_container_add (GTK_CONTAINER (window), tree_view);
+  gtk_widget_realize (tree_view);
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  gtk_tree_store_prepend (store, &iter, NULL);
+  gtk_tree_store_set (store, &iter,
+                      0, "hallo", 1, 1, -1);
+
+  gtk_tree_store_append (store, &child_iter, &iter);
+  gtk_tree_store_set (store, &child_iter,
+                      0, "toemaar", 1, 1, -1);
+
+  gtk_tree_store_append (store, &child_iter2, &child_iter);
+  gtk_tree_store_set (store, &child_iter2,
+                      0, "very deep", 1, 1, -1);
+
+  append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
+
+  gtk_tree_store_append (store, &child_iter, &iter);
+  gtk_tree_store_set (store, &child_iter,
+                      0, "sja", 1, 1, -1);
+
+  gtk_tree_store_append (store, &child_iter, &iter);
+  gtk_tree_store_set (store, &child_iter,
+                      0, "some word", 1, -1, -1);
+
+  /* Expand and collapse the tree */
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  /* Add another it */
+  g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
+                     GINT_TO_POINTER (TRUE));
+
+  if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
+    {
+      gtk_tree_store_append (store, &child_iter, &iter);
+      gtk_tree_store_set (store, &child_iter,
+                          0, "new new new !!", 1, 1, -1);
+    }
+  gtk_tree_path_free (append_path);
+
+  /* Expand */
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+}
+
+
+static gint
+specific_sort_filter_remove_node_compare_func (GtkTreeModel  *model,
+                                               GtkTreeIter   *iter1,
+                                               GtkTreeIter   *iter2,
+                                               gpointer       data)
+{
+  return -1;
+}
+
+static gboolean
+specific_sort_filter_remove_node_visible_func (GtkTreeModel  *model,
+                                               GtkTreeIter   *iter,
+                                               gpointer       data)
+{
+  char *item = NULL;
+
+  /* Do reference the model */
+  gtk_tree_model_get (model, iter, 0, &item, -1);
+  g_free (item);
+
+  return FALSE;
+}
+
+static void
+specific_sort_filter_remove_node (void)
+{
+  /* This test is based on one of the test cases I found in my
+   * old test cases directory.  I unfortunately do not have a record
+   * from who this test case originated.  -Kris.
+   *
+   * General idea:
+   *  - Create tree store, sort, filter models.  The sort model has
+   *    a default sort func that is enabled, filter model a visible func
+   *    that defaults to returning FALSE.
+   *  - Remove a node from the tree store.
+   */
+
+  GtkTreeIter iter;
+  GtkTreeStore *store;
+  GtkTreeModel *filter;
+  GtkTreeModel *sort;
+
+  GtkWidget *window;
+  GtkWidget *tree_view;
+
+  store = gtk_tree_store_new (1, G_TYPE_STRING);
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
+
+  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
+  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
+                                           specific_sort_filter_remove_node_compare_func, NULL, NULL);
+
+  filter = gtk_tree_model_filter_new (sort, NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_sort_filter_remove_node_visible_func,
+                                          filter, NULL);
+
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  tree_view = gtk_tree_view_new_with_model (filter);
+  gtk_container_add (GTK_CONTAINER (window), tree_view);
+  gtk_widget_realize (tree_view);
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  /* Remove a node */
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
+  gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+  gtk_tree_store_remove (store, &iter);
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+}
+
+
+static void
+specific_sort_filter_remove_root (void)
+{
+  /* This test is based on one of the test cases I found in my
+   * old test cases directory.  I unfortunately do not have a record
+   * from who this test case originated.  -Kris.
+   */
+
+  GtkTreeModel *model, *sort, *filter;
+  GtkTreeIter root, mid, leaf;
+  GtkTreePath *path;
+
+  model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
+  gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
+
+  path = gtk_tree_model_get_path (model, &mid);
+
+  sort = gtk_tree_model_sort_new_with_model (model);
+  filter = gtk_tree_model_filter_new (sort, path);
+
+  gtk_tree_path_free (path);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
+
+  g_object_unref (filter);
+  g_object_unref (sort);
+  g_object_unref (model);
+}
+
+
+static void
+specific_root_mixed_visibility (void)
+{
+  int i;
+  GtkTreeModel *filter;
+  /* A bit nasty, apologies */
+  FilterTest fixture;
+
+  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+
+  for (i = 0; i < LEVEL_LENGTH; i++)
+    {
+      GtkTreeIter iter;
+
+      gtk_tree_store_insert (fixture.store, &iter, NULL, i);
+      if (i % 2 == 0)
+        create_tree_store_set_values (fixture.store, &iter, TRUE);
+      else
+        create_tree_store_set_values (fixture.store, &iter, FALSE);
+    }
+
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
+  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+  fixture.monitor = NULL;
+
+  gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
+
+  /* In order to trigger the potential bug, we should not access
+   * the filter model here (so don't call the check functions).
+   */
+
+  /* Change visibility of an odd row to TRUE */
+  set_path_visibility (&fixture, "3", TRUE);
+  check_filter_model (&fixture);
+  check_level_length (fixture.filter, NULL, 4);
+}
+
+
+
+static gboolean
+specific_has_child_filter_filter_func (GtkTreeModel *model,
+                                       GtkTreeIter  *iter,
+                                       gpointer      data)
+{
+  return gtk_tree_model_iter_has_child (model, iter);
+}
+
+static void
+specific_has_child_filter (void)
+{
+  GtkTreeModel *filter;
+  GtkTreeIter iter, root;
+  FilterTest fixture; /* This is not how it should be done */
+  GtkWidget *tree_view;
+
+  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
+  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+  fixture.monitor = signal_monitor_new (filter);
+
+  tree_view = gtk_tree_view_new_with_model (filter);
+
+  /* We will filter on parent state using a filter function.  We will
+   * manually keep the boolean column in sync, so that we can use
+   * check_filter_model() to check the consistency of the model.
+   */
+  /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
+   * to be able to check the structure here.  We keep the calls to
+   * check_filter_model() commented out until then.
+   */
+  gtk_tree_model_filter_set_visible_func (fixture.filter,
+                                          specific_has_child_filter_filter_func,
+                                          NULL, NULL);
+
+  /* The first node will be initially invisible: no signals */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  create_tree_store_set_values (fixture.store, &root, FALSE);
+
+  /* check_filter_model (&fixture); */
+  check_level_length (fixture.filter, NULL, 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Insert a child node. This will cause the parent to become visible
+   * since there is a child now.
+   */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  /* Parent must now be visible.  Do the level length check first,
+   * to avoid modifying the child model triggering a row-changed to
+   * the filter model.
+   */
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* This should propagate row-changed */
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  set_path_visibility (&fixture, "0", TRUE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* New root node, no child, so no signal */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  check_level_length (fixture.filter, NULL, 1);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* When the child comes in, this node will become visible */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  check_level_length (fixture.filter, NULL, 2);
+  check_level_length (fixture.filter, "1", 0);
+
+  create_tree_store_set_values (fixture.store, &root, TRUE);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Add another child for 1 */
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+  check_level_length (fixture.filter, NULL, 2);
+  check_level_length (fixture.filter, "0", 0);
+  check_level_length (fixture.filter, "1", 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Now remove one of the remaining child rows */
+  signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
+                                       &iter, "0:0");
+  gtk_tree_store_remove (fixture.store, &iter);
+
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 0);
+
+  set_path_visibility (&fixture, "0", FALSE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  g_object_unref (fixture.filter);
+  g_object_unref (fixture.store);
+  gtk_widget_destroy (tree_view);
+}
+
+
+static gboolean
+specific_root_has_child_filter_filter_func (GtkTreeModel *model,
+                                            GtkTreeIter  *iter,
+                                            gpointer      data)
+{
+  int depth;
+  GtkTreePath *path;
+
+  path = gtk_tree_model_get_path (model, iter);
+  depth = gtk_tree_path_get_depth (path);
+  gtk_tree_path_free (path);
+
+  if (depth > 1)
+    return TRUE;
+  /* else */
+  return gtk_tree_model_iter_has_child (model, iter);
+}
+
+static void
+specific_root_has_child_filter (void)
+{
+  GtkTreeModel *filter;
+  GtkTreeIter iter, root;
+  FilterTest fixture; /* This is not how it should be done ... */
+  GtkWidget *tree_view;
+
+  /* This is a variation on the above test case, specific has-child-filter,
+   * herein the has-child check for visibility only applies to root level
+   * nodes.  In this test, children are always visible because we
+   * only filter based on the "has child" criterion.
+   */
+
+  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
+  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+  fixture.monitor = signal_monitor_new (filter);
+
+  tree_view = gtk_tree_view_new_with_model (filter);
+
+  /* We will filter on parent state using a filter function.  We will
+   * manually keep the boolean column in sync, so that we can use
+   * check_filter_model() to check the consistency of the model.
+   */
+  /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
+   * to be able to check the structure here.  We keep the calls to
+   * check_filter_model() commented out until then.
+   */
+  gtk_tree_model_filter_set_visible_func (fixture.filter,
+                                          specific_root_has_child_filter_filter_func,
+                                          NULL, NULL);
+
+  /* Add a first node, this will be invisible initially, so no signal
+   * should be emitted.
+   */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  create_tree_store_set_values (fixture.store, &root, FALSE);
+
+  signal_monitor_assert_is_empty (fixture.monitor);
+  /* check_filter_model (&fixture); */
+  check_level_length (fixture.filter, NULL, 0);
+
+  /* Add a child node.  This will cause the parent to become visible,
+   * so we expect row-inserted signals for both.
+   */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 1);
+
+  /* Modify the content of iter, no signals because the parent is not
+   * expanded.
+   */
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Parent must now be visible.  Do the level length check first,
+   * to avoid modifying the child model triggering a row-changed to
+   * the filter model.
+   */
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 1);
+
+  /* Modify path 0 */
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  set_path_visibility (&fixture, "0", TRUE);
+  /* check_filter_model (&fixture); */
+
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Insert another node in the root level.  Initially invisible, so
+   * not expecting any signal.
+   */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  check_level_length (fixture.filter, NULL, 1);
+
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Adding a child node which also makes parent at path 1 visible. */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  check_level_length (fixture.filter, NULL, 2);
+  check_level_length (fixture.filter, "1", 1);
+
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Check if row-changed is propagated */
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
+  create_tree_store_set_values (fixture.store, &root, TRUE);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Insert another child under node 1 */
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+  check_level_length (fixture.filter, NULL, 2);
+  check_level_length (fixture.filter, "0", 1);
+  check_level_length (fixture.filter, "1", 2);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Set a child node to invisible.  This should not yield any
+   * change, because filtering is only done on whether the root
+   * node has a child, which it still has.
+   */
+  set_path_visibility (&fixture, "0:0", FALSE);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Now remove one of the remaining child rows */
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
+                                       &iter, "0:0");
+  gtk_tree_store_remove (fixture.store, &iter);
+
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 2);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Set visibility of 0 to FALSE, no-op for filter model since
+   * the child 0:0 is already gone
+   */
+  set_path_visibility (&fixture, "0", FALSE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  g_object_unref (fixture.filter);
+  g_object_unref (fixture.store);
+  gtk_widget_destroy (tree_view);
+}
+
+static void
+specific_has_child_filter_on_sort_model (void)
+{
+  GtkTreeModel *filter;
+  GtkTreeModel *sort_model;
+  GtkTreeIter iter, root;
+  FilterTest fixture; /* This is not how it should be done */
+  GtkWidget *tree_view;
+
+  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+  sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
+  filter = gtk_tree_model_filter_new (sort_model, NULL);
+  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+  fixture.monitor = signal_monitor_new (filter);
+
+  tree_view = gtk_tree_view_new_with_model (filter);
+
+  /* We will filter on parent state using a filter function.  We will
+   * manually keep the boolean column in sync, so that we can use
+   * check_filter_model() to check the consistency of the model.
+   */
+  /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
+   * to be able to check the structure here.  We keep the calls to
+   * check_filter_model() commented out until then.
+   */
+  gtk_tree_model_filter_set_visible_func (fixture.filter,
+                                          specific_has_child_filter_filter_func,
+                                          NULL, NULL);
+
+  /* The first node will be initially invisible: no signals */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  create_tree_store_set_values (fixture.store, &root, FALSE);
+
+  /* check_filter_model (&fixture); */
+  check_level_length (fixture.filter, NULL, 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Insert a child node. This will cause the parent to become visible
+   * since there is a child now.
+   */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  /* Parent must now be visible.  Do the level length check first,
+   * to avoid modifying the child model triggering a row-changed to
+   * the filter model.
+   */
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* This should propagate row-changed */
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  set_path_visibility (&fixture, "0", TRUE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* New root node, no child, so no signal */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  check_level_length (fixture.filter, NULL, 1);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* When the child comes in, this node will become visible */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  check_level_length (fixture.filter, NULL, 2);
+  check_level_length (fixture.filter, "1", 0);
+
+  create_tree_store_set_values (fixture.store, &root, TRUE);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Add another child for 1 */
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+  check_level_length (fixture.filter, NULL, 2);
+  check_level_length (fixture.filter, "0", 0);
+  check_level_length (fixture.filter, "1", 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Now remove one of the remaining child rows */
+  signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
+                                       &iter, "0:0");
+  gtk_tree_store_remove (fixture.store, &iter);
+
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 0);
+
+  set_path_visibility (&fixture, "0", FALSE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  g_object_unref (fixture.filter);
+  g_object_unref (fixture.store);
+  gtk_widget_destroy (tree_view);
+}
+
+static gboolean
+specific_at_least_2_children_filter_filter_func (GtkTreeModel *model,
+                                                 GtkTreeIter  *iter,
+                                                 gpointer      data)
+{
+  return gtk_tree_model_iter_n_children (model, iter) >= 2;
+}
+
+static void
+specific_at_least_2_children_filter (void)
+{
+  GtkTreeModel *filter;
+  GtkTreeIter iter, root;
+  FilterTest fixture; /* This is not how it should be done */
+  GtkWidget *tree_view;
+
+  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
+  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+  fixture.monitor = signal_monitor_new (filter);
+
+  tree_view = gtk_tree_view_new_with_model (filter);
+
+  gtk_tree_model_filter_set_visible_func (fixture.filter,
+                                          specific_at_least_2_children_filter_filter_func,
+                                          NULL, NULL);
+
+  /* The first node will be initially invisible: no signals */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  create_tree_store_set_values (fixture.store, &root, FALSE);
+
+  /* check_filter_model (&fixture); */
+  check_level_length (fixture.filter, NULL, 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Insert a child node.  Nothing should happen.
+   */
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  check_level_length (fixture.filter, NULL, 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Insert a second child node.  This will cause the parent to become
+   * visible.
+   */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  /* Parent must now be visible.  Do the level length check first,
+   * to avoid modifying the child model triggering a row-changed to
+   * the filter model.
+   */
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* This should propagate row-changed */
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  set_path_visibility (&fixture, "0", TRUE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* New root node, no child, so no signal */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  check_level_length (fixture.filter, NULL, 1);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* First child, no signal, no change */
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  check_level_length (fixture.filter, NULL, 1);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* When the second child comes in, this node will become visible */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  check_level_length (fixture.filter, NULL, 2);
+  check_level_length (fixture.filter, "1", 0);
+
+  create_tree_store_set_values (fixture.store, &root, TRUE);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Add another child for 1 */
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+  check_level_length (fixture.filter, NULL, 2);
+  check_level_length (fixture.filter, "0", 0);
+  check_level_length (fixture.filter, "1", 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Now remove one of the remaining child rows */
+  signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
+
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
+                                       &iter, "0:0");
+  gtk_tree_store_remove (fixture.store, &iter);
+
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 0);
+
+  set_path_visibility (&fixture, "0", FALSE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  g_object_unref (fixture.filter);
+  g_object_unref (fixture.store);
+  gtk_widget_destroy (tree_view);
+}
+
+static void
+specific_at_least_2_children_filter_on_sort_model (void)
+{
+  GtkTreeRowReference *ref;
+  GtkTreeModel *filter;
+  GtkTreeModel *sort_model;
+  GtkTreeIter iter, root;
+  FilterTest fixture; /* This is not how it should be done */
+  GtkWidget *tree_view;
+
+  fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+  sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
+  filter = gtk_tree_model_filter_new (sort_model, NULL);
+  fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+  fixture.monitor = signal_monitor_new (filter);
+
+  tree_view = gtk_tree_view_new_with_model (filter);
+
+  gtk_tree_model_filter_set_visible_func (fixture.filter,
+                                          specific_at_least_2_children_filter_filter_func,
+                                          NULL, NULL);
+
+  /* The first node will be initially invisible: no signals */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  create_tree_store_set_values (fixture.store, &root, FALSE);
+
+  /* check_filter_model (&fixture); */
+  check_level_length (fixture.filter, NULL, 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* Insert a child node.  Nothing should happen.
+   */
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  check_level_length (fixture.filter, NULL, 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+    {
+      GtkTreePath *path = gtk_tree_path_new_from_indices (0, 0, -1);
+
+      ref = gtk_tree_row_reference_new (sort_model, path);
+      gtk_tree_path_free (path);
+    }
+
+  /* Insert a second child node.  This will cause the parent to become
+   * visible.
+   */
+  signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  gtk_tree_store_append (fixture.store, &iter, &root);
+  create_tree_store_set_values (fixture.store, &iter, TRUE);
+
+  /* Parent must now be visible.  Do the level length check first,
+   * to avoid modifying the child model triggering a row-changed to
+   * the filter model.
+   */
+  check_level_length (fixture.filter, NULL, 1);
+  check_level_length (fixture.filter, "0", 0);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* This should propagate row-changed */
+  signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
+  signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
+
+  set_path_visibility (&fixture, "0", TRUE);
+  /* check_filter_model (&fixture); */
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  /* New root node, no child, so no signal */
+  gtk_tree_store_append (fixture.store, &root, NULL);
+  check_level_length (fixture.filter, NULL, 1);
+  signal_monitor_assert_is_empty (fixture.monitor);
+
+  gtk_tree_row_reference_free (ref);
+  g_object_unref (fixture.filter);
+  g_object_unref (fixture.store);
+  gtk_widget_destroy (tree_view);
+}
+
+
+static void
+specific_filter_add_child (void)
+{
+  /* This test is based on one of the test cases I found in my
+   * old test cases directory.  I unfortunately do not have a record
+   * from who this test case originated.  -Kris.
+   */
+
+  GtkTreeIter iter;
+  GtkTreeIter iter_first;
+  GtkTreeIter child;
+  GtkTreeStore *store;
+  GtkTreeModel *filter G_GNUC_UNUSED;
+
+  store = gtk_tree_store_new (1, G_TYPE_STRING);
+
+  gtk_tree_store_append (store, &iter_first, NULL);
+  gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_set (store, &iter, 0, "Hello", -1);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_set (store, &iter, 0, "Hello", -1);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_set (store, &iter, 0, "Hello", -1);
+
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
+
+  gtk_tree_store_set (store, &iter, 0, "Hello", -1);
+  gtk_tree_store_append (store, &child, &iter_first);
+  gtk_tree_store_set (store, &child, 0, "Hello", -1);
+}
+
+static void
+specific_list_store_clear (void)
+{
+  GtkTreeIter iter;
+  GtkListStore *list;
+  GtkTreeModel *filter;
+  GtkWidget *view G_GNUC_UNUSED;
+
+  list = gtk_list_store_new (1, G_TYPE_INT);
+  gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
+  gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
+  gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
+  gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
+  gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
+  gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
+  gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
+  gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
+
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
+  view = gtk_tree_view_new_with_model (filter);
+
+  gtk_list_store_clear (list);
+}
+
+static void
+specific_sort_ref_leaf_and_remove_ancestor (void)
+{
+  GtkTreeIter iter, child, child2, child3;
+  GtkTreeStore *tree;
+  GtkTreeModel *sort;
+  GtkTreePath *path;
+  GtkTreeRowReference *rowref;
+  GtkWidget *view G_GNUC_UNUSED;
+
+  tree = gtk_tree_store_new (1, G_TYPE_INT);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
+
+  gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
+  gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
+  gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
+
+  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
+  view = gtk_tree_view_new_with_model (sort);
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+
+  path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
+  rowref = gtk_tree_row_reference_new (sort, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
+  rowref = gtk_tree_row_reference_new (sort, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (3, 0, -1);
+  rowref = gtk_tree_row_reference_new (sort, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (3, -1);
+  rowref = gtk_tree_row_reference_new (sort, path);
+  gtk_tree_path_free (path);
+
+  /* Deleting a parent */
+  path = gtk_tree_path_new_from_indices (3, 0, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
+  gtk_tree_store_remove (tree, &iter);
+  gtk_tree_path_free (path);
+
+  gtk_tree_row_reference_free (rowref);
+}
+
+static void
+specific_ref_leaf_and_remove_ancestor (void)
+{
+  GtkTreeIter iter, child, child2, child3;
+  GtkTreeStore *tree;
+  GtkTreeModel *filter;
+  GtkTreePath *path;
+  GtkTreeRowReference *rowref;
+  GtkWidget *view G_GNUC_UNUSED;
+
+  tree = gtk_tree_store_new (1, G_TYPE_INT);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
+
+  gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
+  gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
+  gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
+
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), NULL);
+  view = gtk_tree_view_new_with_model (filter);
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+
+  path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
+  rowref = gtk_tree_row_reference_new (filter, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
+  rowref = gtk_tree_row_reference_new (filter, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (3, 0, -1);
+  rowref = gtk_tree_row_reference_new (filter, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (3, -1);
+  rowref = gtk_tree_row_reference_new (filter, path);
+  gtk_tree_path_free (path);
+
+  /* Deleting a parent */
+  path = gtk_tree_path_new_from_indices (3, 0, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
+  gtk_tree_store_remove (tree, &iter);
+  gtk_tree_path_free (path);
+
+  gtk_tree_row_reference_free (rowref);
+}
+
+static void
+specific_virtual_ref_leaf_and_remove_ancestor (void)
+{
+  GtkTreeIter iter, child, child2, child3;
+  GtkTreeStore *tree;
+  GtkTreeModel *filter;
+  GtkTreePath *path;
+  GtkTreeRowReference *rowref;
+  GtkWidget *view G_GNUC_UNUSED;
+
+  tree = gtk_tree_store_new (1, G_TYPE_INT);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
+  gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
+
+  gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
+  gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
+  gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
+
+  /* Set a virtual root of 3:0 */
+  path = gtk_tree_path_new_from_indices (3, 0, -1);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
+  gtk_tree_path_free (path);
+
+  view = gtk_tree_view_new_with_model (filter);
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+
+  path = gtk_tree_path_new_from_indices (0, 0, -1);
+  rowref = gtk_tree_row_reference_new (filter, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (0, 0, -1);
+  rowref = gtk_tree_row_reference_new (filter, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (0, -1);
+  rowref = gtk_tree_row_reference_new (filter, path);
+  gtk_tree_path_free (path);
+
+  /* Deleting the virtual root */
+  path = gtk_tree_path_new_from_indices (3, 0, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
+  gtk_tree_store_remove (tree, &iter);
+  gtk_tree_path_free (path);
+
+  gtk_tree_row_reference_free (rowref);
+}
+
+
+static int
+specific_bug_301558_sort_func (GtkTreeModel *model,
+                               GtkTreeIter  *a,
+                               GtkTreeIter  *b,
+                               gpointer      data)
+{
+  int i, j;
+
+  gtk_tree_model_get (model, a, 0, &i, -1);
+  gtk_tree_model_get (model, b, 0, &j, -1);
+
+  return j - i;
+}
+
+static void
+specific_bug_301558 (void)
+{
+  /* Test case for GNOME Bugzilla bug 301558 provided by
+   * Markku Vire.
+   */
+  GtkTreeStore *tree;
+  GtkTreeModel *filter;
+  GtkTreeModel *sort;
+  GtkTreeIter root, iter, iter2;
+  GtkWidget *view G_GNUC_UNUSED;
+  int i;
+  gboolean add;
+
+  g_test_bug ("301558");
+
+  tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
+  gtk_tree_store_append (tree, &iter, NULL);
+  gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
+  gtk_tree_store_append (tree, &iter2, &iter);
+  gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
+
+  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
+  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
+                                           specific_bug_301558_sort_func,
+                                           NULL, NULL);
+
+  filter = gtk_tree_model_filter_new (sort, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
+
+  view = gtk_tree_view_new_with_model (filter);
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  add = TRUE;
+
+  for (i = 0; i < 10; i++)
+    {
+      if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
+        g_assert_not_reached ();
+
+      if (add)
+        {
+          gtk_tree_store_append (tree, &iter, &root);
+          gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
+        }
+      else
+        {
+          int n;
+          n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
+          gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
+                                         &root, n - 1);
+          gtk_tree_store_remove (tree, &iter);
+        }
+
+      add = !add;
+    }
+}
+
+
+static gboolean
+specific_bug_311955_filter_func (GtkTreeModel *model,
+                                 GtkTreeIter  *iter,
+                                 gpointer      data)
+{
+  int value;
+
+  gtk_tree_model_get (model, iter, 0, &value, -1);
+
+  return (value != 0);
+}
+
+static void
+specific_bug_311955 (void)
+{
+  /* This is a test case for GNOME Bugzilla bug 311955.  It was written
+   * by Markku Vire.
+   */
+  GtkTreeIter iter, child, root;
+  GtkTreeStore *store;
+  GtkTreeModel *sort;
+  GtkTreeModel *filter;
+
+  GtkWidget *window G_GNUC_UNUSED;
+  GtkWidget *tree_view;
+  int i;
+  int n;
+  GtkTreePath *path;
+
+  g_test_bug ("311955");
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_append (store, &root, NULL);
+  gtk_tree_store_set (store, &root, 0, 33, -1);
+
+  gtk_tree_store_append (store, &iter, &root);
+  gtk_tree_store_set (store, &iter, 0, 50, -1);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_set (store, &iter, 0, 22, -1);
+
+  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
+  filter = gtk_tree_model_filter_new (sort, NULL);
+
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_bug_311955_filter_func,
+                                          NULL, NULL);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  tree_view = gtk_tree_view_new_with_model (filter);
+  g_object_unref (store);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
+
+  /* Fill model */
+  for (i = 0; i < 4; i++)
+    {
+      gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
+
+      gtk_tree_store_append (store, &iter, &root);
+
+      if (i < 3)
+        gtk_tree_store_set (store, &iter, 0, i, -1);
+
+      if (i % 2 == 0)
+        {
+          gtk_tree_store_append (store, &child, &iter);
+          gtk_tree_store_set (store, &child, 0, 10, -1);
+        }
+    }
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 1);
+
+  /* Remove bottommost child from the tree. */
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
+  n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
+
+  if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
+    {
+      if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
+        gtk_tree_store_remove (store, &child);
+    }
+  else
+    g_assert_not_reached ();
+
+  path = gtk_tree_path_new_from_indices (0, 2, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+  gtk_tree_path_free (path);
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
+}
+
+static void
+specific_bug_311955_clean (void)
+{
+  /* Cleaned up version of the test case for GNOME Bugzilla bug 311955,
+   * which is easier to understand.
+   */
+  GtkTreeIter iter, child, grandchild;
+  GtkTreeStore *store;
+  GtkTreeModel *sort;
+  GtkTreeModel *filter;
+
+  GtkWidget *tree_view;
+  GtkTreePath *path;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_set (store, &iter, 0, 1, -1);
+
+  gtk_tree_store_append (store, &child, &iter);
+  gtk_tree_store_set (store, &child, 0, 1, -1);
+
+  sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
+  filter = gtk_tree_model_filter_new (sort, NULL);
+
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_bug_311955_filter_func,
+                                          NULL, NULL);
+
+  tree_view = gtk_tree_view_new_with_model (filter);
+  g_object_unref (store);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
+
+  gtk_tree_store_append (store, &child, &iter);
+  gtk_tree_store_set (store, &child, 0, 0, -1);
+
+  gtk_tree_store_append (store, &child, &iter);
+  gtk_tree_store_set (store, &child, 0, 1, -1);
+
+  gtk_tree_store_append (store, &child, &iter);
+  gtk_tree_store_set (store, &child, 0, 1, -1);
+
+  gtk_tree_store_append (store, &grandchild, &child);
+  gtk_tree_store_set (store, &grandchild, 0, 1, -1);
+
+  gtk_tree_store_append (store, &child, &iter);
+  /* Don't set a value: assume 0 */
+
+  /* Remove leaf node, check trigger row-has-child-toggled */
+  path = gtk_tree_path_new_from_indices (0, 3, 0, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
+  gtk_tree_path_free (path);
+  gtk_tree_store_remove (store, &iter);
+
+  path = gtk_tree_path_new_from_indices (0, 2, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+  gtk_tree_path_free (path);
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
+
+  gtk_widget_destroy (tree_view);
+}
+
+static void
+specific_bug_346800 (void)
+{
+  /* This is a test case for GNOME Bugzilla bug 346800.  It was written
+   * by Jonathan Matthew.
+   */
+
+  GtkTreeIter node_iters[50];
+  GtkTreeIter child_iters[50];
+  GtkTreeModel *model;
+  GtkTreeModelFilter *filter;
+  GtkTreeStore *store;
+  GType *columns;
+  int i;
+  int items = 50;
+  columns = g_new (GType, 2);
+  columns[0] = G_TYPE_STRING;
+  columns[1] = G_TYPE_BOOLEAN;
+  store = gtk_tree_store_newv (2, columns);
+  model = GTK_TREE_MODEL (store);
+
+  g_test_bug ("346800");
+
+  filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
+  gtk_tree_model_filter_set_visible_column (filter, 1);
+
+  for (i=0; i<items; i++)
+    {
+      /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
+
+      g_malloc (138);
+      gtk_tree_store_append (store, &node_iters[i], NULL);
+      gtk_tree_store_set (store, &node_iters[i],
+                          0, "something",
+                          1, ((i%6) == 0) ? FALSE : TRUE,
+                          -1);
+
+      g_malloc (47);
+      gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
+      gtk_tree_store_set (store, &child_iters[i],
+                          0, "something else",
+                          1, FALSE,
+                          -1);
+      gtk_tree_model_filter_refilter (filter);
+
+      if (i > 6)
+        {
+          gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
+                              (i & 1) ? TRUE : FALSE, -1);
+          gtk_tree_model_filter_refilter (filter);
+
+          gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
+                              (i & 1) ? FALSE: TRUE, -1);
+          gtk_tree_model_filter_refilter (filter);
+        }
+    }
+}
+
+static gboolean
+specific_bug_464173_visible_func (GtkTreeModel *model,
+                                  GtkTreeIter  *iter,
+                                  gpointer      data)
+{
+  gboolean *visible = (gboolean *)data;
+
+  return *visible;
+}
+
+static void
+specific_bug_464173 (void)
+{
+  /* Test case for GNOME Bugzilla bug 464173, test case written
+   * by Andreas Koehler.
+   */
+  GtkTreeStore *model;
+  GtkTreeModelFilter *f_model;
+  GtkTreeIter iter1, iter2;
+  GtkWidget *view G_GNUC_UNUSED;
+  gboolean visible = TRUE;
+
+  g_test_bug ("464173");
+
+  model = gtk_tree_store_new (1, G_TYPE_STRING);
+  gtk_tree_store_append (model, &iter1, NULL);
+  gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
+  gtk_tree_store_append (model, &iter2, &iter1);
+  gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
+
+  f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
+  gtk_tree_model_filter_set_visible_func (f_model,
+                                          specific_bug_464173_visible_func,
+                                          &visible, NULL);
+
+  view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
+
+  visible = FALSE;
+  gtk_tree_model_filter_refilter (f_model);
+}
+
+
+static gboolean
+specific_bug_540201_filter_func (GtkTreeModel *model,
+                                 GtkTreeIter  *iter,
+                                 gpointer      data)
+{
+  gboolean has_children;
+
+  has_children = gtk_tree_model_iter_has_child (model, iter);
+
+  return has_children;
+}
+
+static void
+specific_bug_540201 (void)
+{
+  /* Test case for GNOME Bugzilla bug 540201, steps provided by
+   * Charles Day.
+   */
+  GtkTreeIter iter, root;
+  GtkTreeStore *store;
+  GtkTreeModel *filter;
+
+  GtkWidget *tree_view G_GNUC_UNUSED;
+
+  g_test_bug ("540201");
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_append (store, &root, NULL);
+  gtk_tree_store_set (store, &root, 0, 33, -1);
+
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
+  tree_view = gtk_tree_view_new_with_model (filter);
+
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_bug_540201_filter_func,
+                                          NULL, NULL);
+
+  gtk_tree_store_append (store, &iter, &root);
+  gtk_tree_store_set (store, &iter, 0, 50, -1);
+
+  gtk_tree_store_append (store, &iter, &root);
+  gtk_tree_store_set (store, &iter, 0, 22, -1);
+
+
+  gtk_tree_store_append (store, &root, NULL);
+  gtk_tree_store_set (store, &root, 0, 33, -1);
+
+  gtk_tree_store_append (store, &iter, &root);
+  gtk_tree_store_set (store, &iter, 0, 22, -1);
+}
+
+
+static gboolean
+specific_bug_549287_visible_func (GtkTreeModel *model,
+                                  GtkTreeIter  *iter,
+                                  gpointer      data)
+{
+  gboolean result = FALSE;
+
+  result = gtk_tree_model_iter_has_child (model, iter);
+
+  return result;
+}
+
+static void
+specific_bug_549287 (void)
+{
+  /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
+
+  int i;
+  GtkTreeStore *store;
+  GtkTreeModel *filtered;
+  GtkWidget *view G_GNUC_UNUSED;
+  GtkTreeIter iter;
+  GtkTreeIter *swap, *parent, *child;
+
+  g_test_bug ("529287");
+
+  store = gtk_tree_store_new (1, G_TYPE_STRING);
+  filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
+                                          specific_bug_549287_visible_func,
+                                          NULL, NULL);
+
+  view = gtk_tree_view_new_with_model (filtered);
+
+  for (i = 0; i < 4; i++)
+    {
+      if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
+        {
+          parent = gtk_tree_iter_copy (&iter);
+          child = gtk_tree_iter_copy (&iter);
+
+          while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
+                                                child, parent, 0))
+            {
+
+              swap = parent;
+              parent = child;
+              child = swap;
+            }
+
+          gtk_tree_store_append (store, child, parent);
+          gtk_tree_store_set (store, child,
+                              0, "Something",
+                              -1);
+
+          gtk_tree_iter_free (parent);
+          gtk_tree_iter_free (child);
+        }
+      else
+        {
+          gtk_tree_store_append (store, &iter, NULL);
+          gtk_tree_store_set (store, &iter,
+                              0, "Something",
+                              -1);
+        }
+
+      /* since we inserted something, we changed the visibility conditions: */
+      gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
+    }
+}
+
+static gboolean
+specific_bug_621076_visible_func (GtkTreeModel *model,
+                                  GtkTreeIter  *iter,
+                                  gpointer      data)
+{
+  gboolean visible = FALSE;
+  gchar *str = NULL;
+
+  gtk_tree_model_get (model, iter, 0, &str, -1);
+  if (str != NULL && g_str_has_prefix (str, "visible"))
+    {
+      visible = TRUE;
+    }
+  else
+    {
+      GtkTreeIter child_iter;
+      gboolean valid;
+
+      /* Recursively check if we have a visible child */
+      for (valid = gtk_tree_model_iter_children (model, &child_iter, iter);
+           valid; valid = gtk_tree_model_iter_next (model, &child_iter))
+        {
+          if (specific_bug_621076_visible_func (model, &child_iter, data))
+            {
+              visible = TRUE;
+              break;
+            }
+        }
+    }
+
+  if (str)
+    g_free (str);
+
+  return visible;
+}
+
+static void
+specific_bug_621076 (void)
+{
+  /* Test case for GNOME Bugzilla bug 621076, provided by Xavier Claessens */
+
+  /* This test case differs from has-child-filter and root-has-child-filter
+   * in that the visible function both filters on content and model
+   * structure.  Also, it is recursive.
+   */
+
+  GtkTreeStore *store;
+  GtkTreeModel *filter;
+  GtkWidget *view;
+  GtkTreeIter group_iter;
+  GtkTreeIter item_iter;
+  SignalMonitor *monitor;
+
+  g_test_bug ("621076");
+
+  store = gtk_tree_store_new (1, G_TYPE_STRING);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_bug_621076_visible_func,
+                                          NULL, NULL);
+
+  view = gtk_tree_view_new_with_model (filter);
+  g_object_ref_sink (view);
+
+  monitor = signal_monitor_new (filter);
+
+  signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
+  gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
+                                     0, "visible-group-0",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* visible-group-0 is not expanded, so ROW_INSERTED should not be emitted
+   * for its children. However, ROW_HAS_CHILD_TOGGLED should be emitted on
+   * visible-group-0 to tell the view that row can be expanded. */
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
+  group_iter = item_iter;
+  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
+                                     0, "visible-0:0",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  signal_monitor_append_signal (monitor, ROW_INSERTED, "1");
+  gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
+                                     0, "visible-group-1",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* We are adding an hidden item inside visible-group-1, so
+   * ROW_HAS_CHILD_TOGGLED should not be emitted.  It is emitted though,
+   * because the signal originating at TreeStore will be propagated,
+   * as well a generated signal because the state of the parent *could*
+   * change by a change in the model.
+   */
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  group_iter = item_iter;
+  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
+                                     0, "group-1:0",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* This group is invisible and its parent too. Nothing should be emitted */
+  group_iter = item_iter;
+  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
+                                     0, "group-1:0:0",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* Adding a visible item in this group hierarchy will make all nodes
+   * in this path visible.  The first level should simply tell the view
+   * that it now has a child, and the view will load the tree if needed
+   * (depends on the expanded state).
+   */
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  group_iter = item_iter;
+  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
+                                     0, "visible-1:0:0:0",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  check_level_length (GTK_TREE_MODEL_FILTER (filter), "1", 1);
+
+  gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
+                                     0, "group-2",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* Parent is invisible, and adding this invisible item won't change that,
+   * so no signal should be emitted. */
+  group_iter = item_iter;
+  gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
+                                     0, "invisible-2:0",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* This makes group-2 visible, so it gets inserted and tells it has
+   * children.
+   */
+  signal_monitor_append_signal (monitor, ROW_INSERTED, "2");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
+                                     0, "visible-2:1",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* group-2 is already visible, so this time it is a normal insertion */
+  gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
+                                     0, "visible-2:2",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+
+  gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
+                                     0, "group-3",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* Parent is invisible, and adding this invisible item won't change that,
+   * so no signal should be emitted. */
+  group_iter = item_iter;
+  gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
+                                     0, "invisible-3:0",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
+                                     0, "invisible-3:1",
+                                     -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* This will make group 3 visible. */
+  signal_monitor_append_signal (monitor, ROW_INSERTED, "3");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
+  gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* Make sure all groups are expanded, so the filter has the tree cached */
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  /* Should only yield a row-changed */
+  signal_monitor_append_signal (monitor, ROW_CHANGED, "3:0");
+  gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* Now remove/hide some items. If a group loses its last item, the group
+   * should be deleted instead of the item.
+   */
+
+  signal_monitor_append_signal (monitor, ROW_DELETED, "2:1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:2");
+  gtk_tree_store_remove (store, &item_iter);
+  signal_monitor_assert_is_empty (monitor);
+
+  signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  signal_monitor_append_signal (monitor, ROW_DELETED, "2");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:1");
+  gtk_tree_store_set (store, &item_iter, 0, "invisible-2:1", -1);
+  signal_monitor_assert_is_empty (monitor);
+
+  signal_monitor_append_signal (monitor, ROW_DELETED, "1:0:0:0");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1:0:0");
+  signal_monitor_append_signal (monitor, ROW_DELETED, "1:0");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "1:0:0:0");
+  gtk_tree_store_remove (store, &item_iter);
+  signal_monitor_assert_is_empty (monitor);
+
+  /* Hide a group using row-changed instead of row-deleted */
+  /* Caution: group 2 is gone, so offsets of the signals have moved. */
+  signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
+  signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
+  signal_monitor_append_signal (monitor, ROW_DELETED, "2");
+  gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter,
+                                       "3:1");
+  gtk_tree_store_set (store, &item_iter, 0, "invisible-3:1", -1);
+  signal_monitor_assert_is_empty (monitor);
+
+#if 0
+  {
+    GtkWidget *window;
+    GtkTreeViewColumn *col;
+
+    gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+
+    col = gtk_tree_view_column_new_with_attributes ("foo",
+        gtk_cell_renderer_text_new (),
+        "text", 0, NULL);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
+
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    g_signal_connect (window, "delete-event",
+        G_CALLBACK (gtk_widget_destroy), NULL);
+    g_signal_connect (window, "destroy",
+        G_CALLBACK (gtk_main_quit), NULL);
+
+    gtk_container_add (GTK_CONTAINER (window), view);
+
+    gtk_widget_show (view);
+    gtk_widget_show (window);
+
+    gtk_main ();
+  }
+#endif
+
+  /* Cleanup */
+  signal_monitor_free (monitor);
+  g_object_unref (view);
+  g_object_unref (store);
+  g_object_unref (filter);
+}
+
+static void
+specific_bug_657353_related (void)
+{
+  GtkTreeIter node1, node2, node3, node4;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *filter_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_BOOLEAN };
+
+  /* gtk_tree_model_filter_rows_reordered() used to have a problem to
+   * not properly transfer the first ref count when the first node in
+   * the level does not have elt->offset == 0.  This test checks for
+   * that.  This bug could cause the faulty condition
+   *   elt->ext_ref_count > elt->ref_count
+   * to raise.
+   */
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &node1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &node2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &node3, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &node4, NULL);
+
+  /* Hide the first node */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &node1, 0, FALSE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &node2, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &node3, 0, TRUE, -1);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &node4, 0, TRUE, -1);
+
+  filter_model = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter_model), 0);
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  assert_node_ref_count (ref_model, &node1, 0);
+  assert_node_ref_count (ref_model, &node2, 2);
+  assert_node_ref_count (ref_model, &node3, 1);
+  assert_node_ref_count (ref_model, &node4, 1);
+
+  /* Swap nodes 2 and 3 */
+
+  /* gtk_tree_store_swap() will emit rows-reordered */
+  gtk_tree_store_swap (GTK_TREE_STORE (model),
+                       &node2, &node3);
+
+  assert_node_ref_count (ref_model, &node1, 0);
+  assert_node_ref_count (ref_model, &node3, 2);
+  assert_node_ref_count (ref_model, &node2, 1);
+  assert_node_ref_count (ref_model, &node4, 1);
+
+  /* Hide node 3 */
+  gtk_tree_store_set (GTK_TREE_STORE (model), &node3, 0, FALSE, -1);
+
+  assert_node_ref_count (ref_model, &node1, 0);
+  assert_node_ref_count (ref_model, &node3, 0);
+  assert_node_ref_count (ref_model, &node2, 2);
+  assert_node_ref_count (ref_model, &node4, 1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (ref_model);
+}
+
+static gboolean
+specific_bug_657353_visible_func (GtkTreeModel *model,
+                                  GtkTreeIter  *iter,
+                                  gpointer      data)
+{
+  gchar *str;
+  gboolean ret = FALSE;
+
+  gtk_tree_model_get (model, iter, 0, &str, -1);
+  ret = strstr (str, "hidden") ? FALSE : TRUE;
+  g_free (str);
+
+  return ret;
+}
+
+static void
+specific_bug_657353 (void)
+{
+  GtkListStore *store;
+  GtkTreeModel *sort_model;
+  GtkTreeModel *filter_model;
+  GtkTreeIter iter, iter_a, iter_b, iter_c;
+  GtkWidget *tree_view;
+
+  /* This is a very carefully crafted test case that is triggering the
+   * situation described in bug 657353.
+   *
+   *   GtkListStore acts like EphyCompletionModel
+   *   GtkTreeModelSort acts like the sort model added in
+   *                      ephy_location_entry_set_completion.
+   *   GtkTreeModelFilter acts like the filter model in
+   *                      GtkEntryCompletion.
+   */
+
+  /* Set up a model that's wrapped in a GtkTreeModelSort.  The first item
+   * will be hidden.
+   */
+  store = gtk_list_store_new (1, G_TYPE_STRING);
+  gtk_list_store_insert_with_values (store, &iter_b, 0, 0, "BBB hidden", -1);
+  gtk_list_store_insert_with_values (store, &iter, 1, 0, "EEE", -1);
+  gtk_list_store_insert_with_values (store, &iter, 2, 0, "DDD", -1);
+  gtk_list_store_insert_with_values (store, &iter_c, 3, 0, "CCC", -1);
+
+  sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
+
+  filter_model = gtk_tree_model_filter_new (sort_model, NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model),
+                                          specific_bug_657353_visible_func,
+                                          filter_model, NULL);
+
+  tree_view = gtk_tree_view_new_with_model (filter_model);
+
+  /* This triggers emission of rows-reordered.  The elt with offset == 0
+   * is hidden, which used to cause misbehavior.  (The first reference should
+   * have moved to CCC, which did not happen).
+   */
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_ASCENDING);
+
+  /* By inserting another item that will appear at the first position, a
+   * reference transfer is done from CCC (which failed to get this reference
+   * earlier) to AAA.  At this point, the rule
+   * elt->ref_count >= elt->ext_ref_count is broken for CCC.
+   */
+  gtk_list_store_insert_with_values (store, &iter_a, 6, 0, "AAA", -1);
+
+  /* When we hide CCC, the references cannot be correctly released, because
+   * CCC failed to get a reference during rows-reordered.  The faulty condition
+   * only manifests itself here with MODEL_FILTER_DEBUG disabled (as is usual
+   * in production).
+   */
+  gtk_list_store_set (store, &iter_c, 0, "CCC hidden", -1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter_model);
+  g_object_unref (sort_model);
+  g_object_unref (store);
+}
+
+static void
+specific_bug_658696 (void)
+{
+  GtkTreeStore *store;
+  GtkTreeModel *filter;
+  GtkTreePath *vroot;
+  GtkTreeIter iter;
+
+  store = create_tree_store (4, TRUE);
+
+  vroot = gtk_tree_path_new_from_indices (0, 0, -1);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), vroot);
+  gtk_tree_path_free (vroot);
+
+  /* This used to cause a crash in gtk_tree_model_filter_check_ancestors() */
+  gtk_tree_store_append (store, &iter, NULL);
+
+  g_object_unref (store);
+  g_object_unref (filter);
+}
+
+static gboolean
+specific_bug_659022_visible_func (GtkTreeModel *model,
+                                  GtkTreeIter  *iter,
+                                  gpointer      data)
+{
+  GtkTreeIter tmp;
+
+  if (!gtk_tree_model_iter_parent (model, &tmp, iter))
+    {
+      if (gtk_tree_model_iter_n_children (model, iter) >= 2)
+        return TRUE;
+      else
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+specific_bug_659022_row_changed_emission (void)
+{
+  GtkTreeModel *filter;
+  GtkTreeModel *model;
+  GtkTreeIter parent, child, child2;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+
+  filter = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_bug_659022_visible_func,
+                                          NULL, NULL);
+
+  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (filter));
+
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent, NULL, 0);
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &child, &parent, 0);
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &child2, &parent, 0);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter));
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
+
+  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter));
+
+  path = gtk_tree_model_get_path (model, &child);
+  gtk_tree_model_row_changed (model, path, &child);
+  gtk_tree_path_free (path);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter);
+  g_object_unref (model);
+}
+
+static void
+specific_bug_659022_row_deleted_node_invisible (void)
+{
+  GtkTreeModel *filter;
+  GtkTreeModel *model;
+  GtkTreeIter parent, child;
+  GtkTreeIter parent2, child2, child3;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+
+  filter = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_bug_659022_visible_func,
+                                          NULL, NULL);
+
+  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (filter));
+
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent, NULL, 0);
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &child, &parent, 0);
+
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent2, NULL, 0);
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &child2, &parent2, 0);
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &child3, &parent2, 0);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter));
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter);
+  g_object_unref (model);
+}
+
+static void
+specific_bug_659022_row_deleted_free_level (void)
+{
+  GtkTreeModel *filter;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeIter parent, child;
+  GtkTreeIter parent2, child2, child3;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  filter = gtk_tree_model_filter_new (model, NULL);
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
+                                          specific_bug_659022_visible_func,
+                                          NULL, NULL);
+
+  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (filter));
+
+  /* Carefully construct a model */
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent, NULL, 0);
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &child, &parent, 0);
+
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &parent2, NULL, 0);
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &child2, &parent2, 0);
+  gtk_tree_store_insert (GTK_TREE_STORE (model), &child3, &parent2, 0);
+
+  /* Only parent2 is visible, child3 holds first ref count for that level
+   * (Note that above, both child2 as child3 are inserted at position 0).
+   */
+  assert_node_ref_count (ref_model, &parent, 0);
+  assert_node_ref_count (ref_model, &child, 0);
+  assert_node_ref_count (ref_model, &parent2, 3);
+  assert_node_ref_count (ref_model, &child3, 1);
+  assert_node_ref_count (ref_model, &child2, 0);
+
+  /* Make sure child level is cached */
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &parent, 0);
+  assert_node_ref_count (ref_model, &child, 0);
+  assert_node_ref_count (ref_model, &parent2, 3);
+  assert_node_ref_count (ref_model, &child3, 2);
+  assert_node_ref_count (ref_model, &child2, 1);
+
+  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &parent, 0);
+  assert_node_ref_count (ref_model, &child, 0);
+  assert_node_ref_count (ref_model, &parent2, 3);
+  assert_node_ref_count (ref_model, &child3, 1);
+  assert_node_ref_count (ref_model, &child2, 0);
+
+  /* Remove node with longer child level first */
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (filter);
+  g_object_unref (model);
+}
+
+static void
+specific_bug_679910 (void)
+{
+  GtkTreeModel *filter;
+  GtkListStore *store;
+  GtkTreeIter iter, nil_iter;
+  GtkTreeIter filter_iter;
+
+  store = gtk_list_store_new (1, G_TYPE_POINTER);
+  filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
+
+  gtk_list_store_append (store, &nil_iter);
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_append (store, &nil_iter);
+
+  gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (filter),
+                                                    &filter_iter,
+                                                    &iter);
+  iter = filter_iter;
+  g_return_if_fail (gtk_tree_model_iter_next (filter, &iter));
+  iter = filter_iter;
+  g_return_if_fail (gtk_tree_model_iter_previous (filter, &iter));
+
+  g_object_unref (filter);
+  g_object_unref (store);
+}
+
+/* main */
+
+void
+register_filter_model_tests (void)
+{
+  g_test_add ("/TreeModelFilter/self/verify-test-suite",
+              FilterTest, NULL,
+              filter_test_setup,
+              verify_test_suite,
+              filter_test_teardown);
+
+  g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-1",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup,
+              verify_test_suite_vroot,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-2",
+              FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
+              filter_test_setup,
+              verify_test_suite_vroot,
+              filter_test_teardown);
+
+
+  g_test_add ("/TreeModelFilter/filled/hide-root-level",
+              FilterTest, NULL,
+              filter_test_setup,
+              filled_hide_root_level,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filled/hide-child-levels",
+              FilterTest, NULL,
+              filter_test_setup,
+              filled_hide_child_levels,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filled/hide-child-levels/root-expanded",
+              FilterTest, NULL,
+              filter_test_setup,
+              filled_hide_child_levels_root_expanded,
+              filter_test_teardown);
+
+  g_test_add ("/TreeModelFilter/filled/hide-root-level/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup,
+              filled_vroot_hide_root_level,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup,
+              filled_vroot_hide_child_levels,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot-root-expanded",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup,
+              filled_vroot_hide_child_levels_root_expanded,
+              filter_test_teardown);
+
+
+  g_test_add ("/TreeModelFilter/empty/show-nodes",
+              FilterTest, NULL,
+              filter_test_setup_empty,
+              empty_show_nodes,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/empty/show-multiple-nodes",
+              FilterTest, NULL,
+              filter_test_setup_empty,
+              empty_show_multiple_nodes,
+              filter_test_teardown);
+
+  g_test_add ("/TreeModelFilter/empty/show-nodes/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_empty,
+              empty_vroot_show_nodes,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/empty/show-multiple-nodes/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_empty,
+              empty_vroot_show_multiple_nodes,
+              filter_test_teardown);
+
+
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single",
+              FilterTest, NULL,
+              filter_test_setup_unfiltered,
+              unfiltered_hide_single,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single/root-expanded",
+              FilterTest, NULL,
+              filter_test_setup_unfiltered_root_expanded,
+              unfiltered_hide_single_root_expanded,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single-child",
+              FilterTest, NULL,
+              filter_test_setup_unfiltered,
+              unfiltered_hide_single_child,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/root-expanded",
+              FilterTest, NULL,
+              filter_test_setup_unfiltered_root_expanded,
+              unfiltered_hide_single_child_root_expanded,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level",
+              FilterTest, NULL,
+              filter_test_setup_unfiltered,
+              unfiltered_hide_single_multi_level,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/root-expanded",
+              FilterTest, NULL,
+              filter_test_setup_unfiltered_root_expanded,
+              unfiltered_hide_single_multi_level_root_expanded,
+              filter_test_teardown);
+
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_unfiltered,
+              unfiltered_vroot_hide_single,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_unfiltered,
+              unfiltered_vroot_hide_single_child,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot/root-expanded",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_unfiltered_root_expanded,
+              unfiltered_vroot_hide_single_child_root_expanded,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_unfiltered,
+              unfiltered_vroot_hide_single_multi_level,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot/root-expanded",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_unfiltered_root_expanded,
+              unfiltered_vroot_hide_single_multi_level_root_expanded,
+              filter_test_teardown);
+
+
+
+  g_test_add ("/TreeModelFilter/unfiltered/show-single",
+              FilterTest, NULL,
+              filter_test_setup_empty_unfiltered,
+              unfiltered_show_single,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/show-single-child",
+              FilterTest, NULL,
+              filter_test_setup_empty_unfiltered,
+              unfiltered_show_single_child,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/show-single-child/root-expanded",
+              FilterTest, NULL,
+              filter_test_setup_empty_unfiltered_root_expanded,
+              unfiltered_show_single_child_root_expanded,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level",
+              FilterTest, NULL,
+              filter_test_setup_empty_unfiltered,
+              unfiltered_show_single_multi_level,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/root-expanded",
+              FilterTest, NULL,
+              filter_test_setup_empty_unfiltered_root_expanded,
+              unfiltered_show_single_multi_level_root_expanded,
+              filter_test_teardown);
+
+  g_test_add ("/TreeModelFilter/unfiltered/show-single/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_empty_unfiltered,
+              unfiltered_vroot_show_single,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_empty_unfiltered,
+              unfiltered_vroot_show_single_child,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot/root-expanded",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_empty_unfiltered_root_expanded,
+              unfiltered_vroot_show_single_child_root_expanded,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_empty_unfiltered,
+              unfiltered_vroot_show_single_multi_level,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot/root-expanded",
+              FilterTest, gtk_tree_path_new_from_indices (2, -1),
+              filter_test_setup_empty_unfiltered_root_expanded,
+              unfiltered_vroot_show_single_multi_level_root_expanded,
+              filter_test_teardown);
+
+
+  g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/root-level",
+              FilterTest, NULL,
+              filter_test_setup_unfiltered,
+              unfiltered_rows_reordered_root_level,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/child-level",
+              FilterTest, NULL,
+              filter_test_setup_unfiltered,
+              unfiltered_rows_reordered_child_level,
+              filter_test_teardown);
+
+  g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/first-hidden",
+              FilterTest, NULL,
+              filter_test_setup,
+              filtered_rows_reordered_root_level_first_hidden,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/middle-hidden",
+              FilterTest, NULL,
+              filter_test_setup,
+              filtered_rows_reordered_root_level_middle_hidden,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/first-hidden",
+              FilterTest, NULL,
+              filter_test_setup,
+              filtered_rows_reordered_child_level_first_hidden,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/middle-hidden",
+              FilterTest, NULL,
+              filter_test_setup,
+              filtered_rows_reordered_child_level_middle_hidden,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/4-hidden",
+              FilterTest, NULL,
+              filter_test_setup,
+              filtered_rows_reordered_child_level_4_hidden,
+              filter_test_teardown);
+  g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/all-hidden",
+              FilterTest, NULL,
+              filter_test_setup,
+              filtered_rows_reordered_child_level_all_hidden,
+              filter_test_teardown);
+
+  /* Inserts in child models after creation of filter model */
+  g_test_add_func ("/TreeModelFilter/insert/before",
+                   insert_before);
+  g_test_add_func ("/TreeModelFilter/insert/child",
+                   insert_child);
+
+  /* Removals from child model after creating of filter model */
+  g_test_add_func ("/TreeModelFilter/remove/node",
+                   remove_node);
+  g_test_add_func ("/TreeModelFilter/remove/node-vroot",
+                   remove_node_vroot);
+  g_test_add_func ("/TreeModelFilter/remove/vroot-ancestor",
+                   remove_vroot_ancestor);
+
+  /* Reference counting */
+  g_test_add_func ("/TreeModelFilter/ref-count/single-level",
+                   ref_count_single_level);
+  g_test_add_func ("/TreeModelFilter/ref-count/two-levels",
+                   ref_count_two_levels);
+  g_test_add_func ("/TreeModelFilter/ref-count/three-levels",
+                   ref_count_three_levels);
+  g_test_add_func ("/TreeModelFilter/ref-count/delete-row",
+                   ref_count_delete_row);
+  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-1",
+                   ref_count_filter_row_length_1);
+  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-1-remove-in-root-level",
+                   ref_count_filter_row_length_1_remove_in_root_level);
+  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-1-remove-in-child-level",
+                   ref_count_filter_row_length_1_remove_in_child_level);
+  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-gt-1",
+                   ref_count_filter_row_length_gt_1);
+  g_test_add_func ("/TreeModelFilter/ref-count/filter-row/length-gt-1-visible-children",
+                   ref_count_filter_row_length_gt_1_visible_children);
+  g_test_add_func ("/TreeModelFilter/ref-count/cleanup",
+                   ref_count_cleanup);
+  g_test_add_func ("/TreeModelFilter/ref-count/row-ref",
+                   ref_count_row_ref);
+
+  /* Reference counting, transfer of first reference on
+   * first node in level.  This is a GtkTreeModelFilter-specific
+   * feature.
+   */
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/insert",
+                   ref_count_transfer_root_level_insert);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/remove",
+                   ref_count_transfer_root_level_remove);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/remove/filtered",
+                   ref_count_transfer_root_level_remove_filtered);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/reordered",
+                   ref_count_transfer_root_level_reordered);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/reordered/filtered",
+                   ref_count_transfer_root_level_reordered_filtered);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/filter",
+                   ref_count_transfer_root_level_filter);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/insert",
+                   ref_count_transfer_child_level_insert);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/remove",
+                   ref_count_transfer_child_level_remove);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/remove/filtered",
+                   ref_count_transfer_child_level_remove_filtered);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/reordered",
+                   ref_count_transfer_child_level_reordered);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/reordered/filtered",
+                   ref_count_transfer_child_level_reordered_filtered);
+  g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/filter",
+                   ref_count_transfer_child_level_filter);
+
+  g_test_add_func ("/TreeModelFilter/specific/path-dependent-filter",
+                   specific_path_dependent_filter);
+  g_test_add_func ("/TreeModelFilter/specific/append-after-collapse",
+                   specific_append_after_collapse);
+  g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-node",
+                   specific_sort_filter_remove_node);
+  g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-root",
+                   specific_sort_filter_remove_root);
+  g_test_add_func ("/TreeModelFilter/specific/root-mixed-visibility",
+                   specific_root_mixed_visibility);
+  g_test_add_func ("/TreeModelFilter/specific/has-child-filter",
+                   specific_has_child_filter);
+  g_test_add_func ("/TreeModelFilter/specific/has-child-filter-on-sort-model",
+                   specific_has_child_filter_on_sort_model);
+  g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter",
+                   specific_at_least_2_children_filter);
+  g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter-on-sort-model",
+                   specific_at_least_2_children_filter_on_sort_model);
+  g_test_add_func ("/TreeModelFilter/specific/root-has-child-filter",
+                   specific_root_has_child_filter);
+  g_test_add_func ("/TreeModelFilter/specific/filter-add-child",
+                   specific_filter_add_child);
+  g_test_add_func ("/TreeModelFilter/specific/list-store-clear",
+                   specific_list_store_clear);
+  g_test_add_func ("/TreeModelFilter/specific/sort-ref-leaf-and-remove-ancestor",
+                   specific_sort_ref_leaf_and_remove_ancestor);
+  g_test_add_func ("/TreeModelFilter/specific/ref-leaf-and-remove-ancestor",
+                   specific_ref_leaf_and_remove_ancestor);
+  g_test_add_func ("/TreeModelFilter/specific/virtual-ref-leaf-and-remove-ancestor",
+                   specific_virtual_ref_leaf_and_remove_ancestor);
+
+  g_test_add_func ("/TreeModelFilter/specific/bug-301558",
+                   specific_bug_301558);
+  g_test_add_func ("/TreeModelFilter/specific/bug-311955",
+                   specific_bug_311955);
+  g_test_add_func ("/TreeModelFilter/specific/bug-311955-clean",
+                   specific_bug_311955_clean);
+  g_test_add_func ("/TreeModelFilter/specific/bug-346800",
+                   specific_bug_346800);
+  g_test_add_func ("/TreeModelFilter/specific/bug-464173",
+                   specific_bug_464173);
+  g_test_add_func ("/TreeModelFilter/specific/bug-540201",
+                   specific_bug_540201);
+  g_test_add_func ("/TreeModelFilter/specific/bug-549287",
+                   specific_bug_549287);
+  g_test_add_func ("/TreeModelFilter/specific/bug-621076",
+                   specific_bug_621076);
+  g_test_add_func ("/TreeModelFilter/specific/bug-657353-related",
+                   specific_bug_657353_related);
+  g_test_add_func ("/TreeModelFilter/specific/bug-657353",
+                   specific_bug_657353);
+  g_test_add_func ("/TreeModelFilter/specific/bug-658696",
+                   specific_bug_658696);
+  g_test_add_func ("/TreeModelFilter/specific/bug-659022/row-changed-emission",
+                   specific_bug_659022_row_changed_emission);
+  g_test_add_func ("/TreeModelFilter/specific/bug-659022/row-deleted-node-invisible",
+                   specific_bug_659022_row_deleted_node_invisible);
+  g_test_add_func ("/TreeModelFilter/specific/bug-659022/row-deleted-free-level",
+                   specific_bug_659022_row_deleted_free_level);
+  g_test_add_func ("/TreeModelFilter/specific/bug-679910",
+                   specific_bug_679910);
+}
diff --git a/testsuite/gtk/floating.c b/testsuite/gtk/floating.c
new file mode 100644 (file)
index 0000000..89add67
--- /dev/null
@@ -0,0 +1,55 @@
+/* floatingtest.c - test floating flag uses
+ * Copyright (C) 2005 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <gtk/gtk.h>
+
+static gboolean destroyed = FALSE;
+static void
+destroy (void)
+{
+  destroyed = TRUE;
+}
+
+static void
+floating_tests (void)
+{
+  GtkWidget *widget = g_object_new (GTK_TYPE_LABEL, NULL);
+  g_object_connect (widget, "signal::destroy", destroy, NULL, NULL);
+
+  g_assert (g_object_is_floating (widget));
+
+  g_object_ref_sink (widget);
+  g_assert (!g_object_is_floating (widget));
+
+  g_object_force_floating (G_OBJECT (widget));
+  g_assert (g_object_is_floating (widget));
+
+  g_object_ref_sink (widget);
+  g_assert (!g_object_is_floating (widget));
+
+  g_assert (!destroyed);
+  g_object_unref (widget);
+  g_assert (destroyed);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  gtk_test_init (&argc, &argv);
+  g_test_add_func ("/floatingtest", floating_tests);
+  return g_test_run();
+}
diff --git a/testsuite/gtk/grid.c b/testsuite/gtk/grid.c
new file mode 100644 (file)
index 0000000..436cfa3
--- /dev/null
@@ -0,0 +1,236 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+/* test that attach_next_to picks the places
+ * we expect it to pick, when there is any choice
+ */
+static void
+test_attach (void)
+{
+  GtkGrid *g;
+  GtkWidget *child, *sibling, *z, *A, *B;
+  gint left, top, width, height;
+
+  g = (GtkGrid *)gtk_grid_new ();
+
+  child = gtk_label_new ("a");
+  gtk_grid_attach_next_to (g, child, NULL, GTK_POS_LEFT, 1, 1);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, -1);
+  g_assert_cmpint (top,    ==, 0);
+  g_assert_cmpint (width,  ==, 1);
+  g_assert_cmpint (height, ==, 1);
+
+  sibling = child;
+  child = gtk_label_new ("b");
+  gtk_grid_attach_next_to (g, child, sibling, GTK_POS_RIGHT, 2, 2);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 0);
+  g_assert_cmpint (top,    ==, 0);
+  g_assert_cmpint (width,  ==, 2);
+  g_assert_cmpint (height, ==, 2);
+
+  /* this one should just be ignored */
+  z = gtk_label_new ("z");
+  gtk_grid_attach (g, z, 4, 4, 1, 1);
+
+  child = gtk_label_new ("c");
+  gtk_grid_attach_next_to (g, child, sibling, GTK_POS_BOTTOM, 3, 1);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, -1);
+  g_assert_cmpint (top,    ==, 1);
+  g_assert_cmpint (width,  ==, 3);
+  g_assert_cmpint (height, ==, 1);
+
+  child = gtk_label_new ("u");
+  gtk_grid_attach_next_to (g, child, z, GTK_POS_LEFT, 2, 1);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 2);
+  g_assert_cmpint (top,    ==, 4);
+  g_assert_cmpint (width,  ==, 2);
+  g_assert_cmpint (height, ==, 1);
+
+  child = gtk_label_new ("v");
+  gtk_grid_attach_next_to (g, child, z, GTK_POS_RIGHT, 2, 1);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 5);
+  g_assert_cmpint (top,    ==, 4);
+  g_assert_cmpint (width,  ==, 2);
+  g_assert_cmpint (height, ==, 1);
+
+  child = gtk_label_new ("x");
+  gtk_grid_attach_next_to (g, child, z, GTK_POS_TOP, 1, 2);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 4);
+  g_assert_cmpint (top,    ==, 2);
+  g_assert_cmpint (width,  ==, 1);
+  g_assert_cmpint (height, ==, 2);
+
+  child = gtk_label_new ("x");
+  gtk_grid_attach_next_to (g, child, z, GTK_POS_TOP, 1, 2);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 4);
+  g_assert_cmpint (top,    ==, 2);
+  g_assert_cmpint (width,  ==, 1);
+  g_assert_cmpint (height, ==, 2);
+
+  child = gtk_label_new ("y");
+  gtk_grid_attach_next_to (g, child, z, GTK_POS_BOTTOM, 1, 2);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 4);
+  g_assert_cmpint (top,    ==, 5);
+  g_assert_cmpint (width,  ==, 1);
+  g_assert_cmpint (height, ==, 2);
+
+  A = gtk_label_new ("A");
+  gtk_grid_attach (g, A, 10, 10, 1, 1);
+  B = gtk_label_new ("B");
+  gtk_grid_attach (g, B, 10, 12, 1, 1);
+
+  child  = gtk_label_new ("D");
+  gtk_grid_attach_next_to (g, child, A, GTK_POS_RIGHT, 1, 3);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 11);
+  g_assert_cmpint (top,    ==, 10);
+  g_assert_cmpint (width,  ==,  1);
+  g_assert_cmpint (height, ==,  3);
+}
+
+static void
+test_add (void)
+{
+  GtkGrid *g;
+  GtkWidget *child;
+  gint left, top, width, height;
+
+  g = (GtkGrid *)gtk_grid_new ();
+
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (g), GTK_ORIENTATION_HORIZONTAL);
+
+  child = gtk_label_new ("a");
+  gtk_container_add (GTK_CONTAINER (g), child);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 0);
+  g_assert_cmpint (top,    ==, 0);
+  g_assert_cmpint (width,  ==, 1);
+  g_assert_cmpint (height, ==, 1);
+
+  child = gtk_label_new ("b");
+  gtk_container_add (GTK_CONTAINER (g), child);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 1);
+  g_assert_cmpint (top,    ==, 0);
+  g_assert_cmpint (width,  ==, 1);
+  g_assert_cmpint (height, ==, 1);
+
+  child = gtk_label_new ("c");
+  gtk_container_add (GTK_CONTAINER (g), child);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 2);
+  g_assert_cmpint (top,    ==, 0);
+  g_assert_cmpint (width,  ==, 1);
+  g_assert_cmpint (height, ==, 1);
+
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (g), GTK_ORIENTATION_VERTICAL);
+
+  child = gtk_label_new ("d");
+  gtk_container_add (GTK_CONTAINER (g), child);
+  gtk_container_child_get (GTK_CONTAINER (g), child,
+                           "left-attach", &left,
+                           "top-attach", &top,
+                           "width", &width,
+                           "height", &height,
+                           NULL);
+  g_assert_cmpint (left,   ==, 0);
+  g_assert_cmpint (top,    ==, 1);
+  g_assert_cmpint (width,  ==, 1);
+  g_assert_cmpint (height, ==, 1);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  gtk_test_init (&argc, &argv);
+
+  g_test_add_func ("/grid/attach", test_attach);
+  g_test_add_func ("/grid/add", test_add);
+
+  return g_test_run();
+}
diff --git a/testsuite/gtk/gtkmenu.c b/testsuite/gtk/gtkmenu.c
new file mode 100644 (file)
index 0000000..e2667ba
--- /dev/null
@@ -0,0 +1,452 @@
+#include <gtk/gtk.h>
+
+/* TestItem {{{1 */
+
+/* This utility struct is used by both the RandomMenu and MirrorMenu
+ * class implementations below.
+ */
+typedef struct {
+  GHashTable *attributes;
+  GHashTable *links;
+} TestItem;
+
+static TestItem *
+test_item_new (GHashTable *attributes,
+               GHashTable *links)
+{
+  TestItem *item;
+
+  item = g_slice_new (TestItem);
+  item->attributes = g_hash_table_ref (attributes);
+  item->links = g_hash_table_ref (links);
+
+  return item;
+}
+
+static void
+test_item_free (gpointer data)
+{
+  TestItem *item = data;
+
+  g_hash_table_unref (item->attributes);
+  g_hash_table_unref (item->links);
+
+  g_slice_free (TestItem, item);
+}
+
+/* RandomMenu {{{1 */
+#define MAX_ITEMS 10
+#define TOP_ORDER 4
+
+typedef struct {
+  GMenuModel parent_instance;
+
+  GSequence *items;
+  gint order;
+} RandomMenu;
+
+typedef GMenuModelClass RandomMenuClass;
+
+static GType random_menu_get_type (void);
+G_DEFINE_TYPE (RandomMenu, random_menu, G_TYPE_MENU_MODEL);
+
+static gboolean
+random_menu_is_mutable (GMenuModel *model)
+{
+  return TRUE;
+}
+
+static gint
+random_menu_get_n_items (GMenuModel *model)
+{
+  RandomMenu *menu = (RandomMenu *) model;
+
+  return g_sequence_get_length (menu->items);
+}
+
+static void
+random_menu_get_item_attributes (GMenuModel  *model,
+                                 gint         position,
+                                 GHashTable **table)
+{
+  RandomMenu *menu = (RandomMenu *) model;
+  TestItem *item;
+
+  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
+  *table = g_hash_table_ref (item->attributes);
+}
+
+static void
+random_menu_get_item_links (GMenuModel  *model,
+                            gint         position,
+                            GHashTable **table)
+{
+  RandomMenu *menu = (RandomMenu *) model;
+  TestItem *item;
+
+  item = g_sequence_get (g_sequence_get_iter_at_pos (menu->items, position));
+  *table = g_hash_table_ref (item->links);
+}
+
+static void
+random_menu_finalize (GObject *object)
+{
+  RandomMenu *menu = (RandomMenu *) object;
+
+  g_sequence_free (menu->items);
+
+  G_OBJECT_CLASS (random_menu_parent_class)
+    ->finalize (object);
+}
+
+static void
+random_menu_init (RandomMenu *menu)
+{
+}
+
+static void
+random_menu_class_init (GMenuModelClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  class->is_mutable = random_menu_is_mutable;
+  class->get_n_items = random_menu_get_n_items;
+  class->get_item_attributes = random_menu_get_item_attributes;
+  class->get_item_links = random_menu_get_item_links;
+
+  object_class->finalize = random_menu_finalize;
+}
+
+static RandomMenu * random_menu_new (GRand *rand, gint order);
+
+static void
+random_menu_change (RandomMenu *menu,
+                    GRand      *rand)
+{
+  gint position, removes, adds;
+  GSequenceIter *point;
+  gint n_items;
+  gint i;
+
+  n_items = g_sequence_get_length (menu->items);
+
+  do
+    {
+      position = g_rand_int_range (rand, 0, n_items + 1);
+      removes = g_rand_int_range (rand, 0, n_items - position + 1);
+      adds = g_rand_int_range (rand, 0, MAX_ITEMS - (n_items - removes) + 1);
+    }
+  while (removes == 0 && adds == 0);
+
+  point = g_sequence_get_iter_at_pos (menu->items, position + removes);
+
+  if (removes)
+    {
+      GSequenceIter *start;
+
+      start = g_sequence_get_iter_at_pos (menu->items, position);
+      g_sequence_remove_range (start, point);
+    }
+
+  for (i = 0; i < adds; i++)
+    {
+      const gchar *label;
+      GHashTable *links;
+      GHashTable *attributes;
+
+      attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
+      links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
+
+      if (menu->order > 0 && g_rand_boolean (rand))
+        {
+          RandomMenu *child;
+          const gchar *subtype;
+
+          child = random_menu_new (rand, menu->order - 1);
+
+          if (g_rand_boolean (rand))
+            {
+              subtype = G_MENU_LINK_SECTION;
+              /* label some section headers */
+              if (g_rand_boolean (rand))
+                label = "Section";
+              else
+                label = NULL;
+            }
+          else
+            {
+              /* label all submenus */
+              subtype = G_MENU_LINK_SUBMENU;
+              label = "Submenu";
+            }
+
+          g_hash_table_insert (links, g_strdup (subtype), child);
+        }
+      else
+        /* label all terminals */
+        label = "Menu Item";
+
+      if (label)
+        g_hash_table_insert (attributes, g_strdup ("label"), g_variant_ref_sink (g_variant_new_string (label)));
+
+      g_sequence_insert_before (point, test_item_new (attributes, links));
+      g_hash_table_unref (links);
+      g_hash_table_unref (attributes);
+    }
+
+  g_menu_model_items_changed (G_MENU_MODEL (menu), position, removes, adds);
+}
+
+static RandomMenu *
+random_menu_new (GRand *rand,
+                 gint   order)
+{
+  RandomMenu *menu;
+
+  menu = g_object_new (random_menu_get_type (), NULL);
+  menu->items = g_sequence_new (test_item_free);
+  menu->order = order;
+
+  random_menu_change (menu, rand);
+
+  return menu;
+}
+
+/* Test cases {{{1 */
+
+static void assert_menu_equality (GtkContainer *container, GMenuModel   *model);
+
+static const gchar *
+get_label (GtkMenuItem *item)
+{
+  GList *children = gtk_container_get_children (GTK_CONTAINER (item));
+  const gchar *label = NULL;
+
+  while (children)
+    {
+      if (GTK_IS_CONTAINER (children->data))
+        children = g_list_concat (children, gtk_container_get_children (children->data));
+      else if (GTK_IS_LABEL (children->data))
+        label = gtk_label_get_text (children->data);
+
+      children = g_list_delete_link (children, children);
+    }
+
+  return label;
+}
+
+/* a bit complicated with the separators...
+ *
+ * with_separators are if subsections of this GMenuModel should have
+ * separators inserted between them (ie: in the same sense as the
+ * 'with_separators' argument to gtk_menu_shell_bind_model().
+ *
+ * needs_separator is true if this particular section needs to have a
+ * separator before it in the case that it is non-empty.  this will be
+ * defined for all subsections of a with_separators menu (except the
+ * first) or in case section_header is non-%NULL.
+ *
+ * section_header is the label that must be inside that separator, if it
+ * exists.  section_header is only non-%NULL if needs_separator is also
+ * TRUE.
+ */
+static void
+assert_section_equality (GSList      **children,
+                         gboolean      with_separators,
+                         gboolean      needs_separator,
+                         const gchar  *section_header,
+                         GMenuModel   *model)
+{
+  gboolean has_separator;
+  GSList *our_children;
+  gint i, n;
+
+  /* Assuming that we have the possibility of showing a separator, there
+   * are two valid situations:
+   *
+   *  - we have a separator and we have other children
+   *
+   *  - we have no separator and no children
+   *
+   * If we see a separator, we suppose that it is ours and that we will
+   * encounter children.  In the case that we have no children, the
+   * separator may not be ours but may rather belong to a later section.
+   *
+   * We therefore keep our own copy of the children GSList.  If we
+   * encounter children, we will delete the links that this section is
+   * responsible for and update the pass-by-reference value.  Otherwise,
+   * we will leave everything alone and let the separator be accounted
+   * for by a following section.
+   */
+  our_children = *children;
+  if (needs_separator && GTK_IS_SEPARATOR_MENU_ITEM (our_children->data))
+    {
+       /* We accounted for the separator, at least for now, so remove it
+       * from the list.
+       *
+       * We will check later if we should have actually had a separator
+       * and compare the result to has_separator.
+       */
+      our_children = our_children->next;
+      has_separator = TRUE;
+    }
+  else
+    has_separator = FALSE;
+
+  /* Now, iterate the model checking that the items in the GSList line
+   * up with our expectations. */
+  n = g_menu_model_get_n_items (model);
+  for (i = 0; i < n; i++)
+    {
+      GMenuModel *subsection;
+      GMenuModel *submenu;
+      gchar *label = NULL;
+
+      subsection = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
+      submenu = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);
+      g_menu_model_get_item_attribute (model, i, G_MENU_ATTRIBUTE_LABEL, "s", &label);
+
+      if (subsection)
+        {
+          g_assert (!submenu);
+          assert_section_equality (&our_children,
+                                   FALSE,                                /* with_separators */
+                                   label || (with_separators && i > 0),  /* needs_separator */
+                                   label,                                /* section_header */
+                                   subsection);
+          g_object_unref (subsection);
+        }
+      else
+        {
+          GtkWidget *submenu_widget;
+          GtkMenuItem *item;
+
+          /* This is a normal item.  Make sure the label is right. */
+          item = our_children->data;
+          our_children = g_slist_remove (our_children, item);
+
+          /* get_label() returns "" when it ought to return NULL */
+          g_assert_cmpstr (get_label (item), ==, label ? label : "");
+          submenu_widget = gtk_menu_item_get_submenu (item);
+
+          if (submenu)
+            {
+              g_assert (submenu_widget != NULL);
+              assert_menu_equality (GTK_CONTAINER (submenu_widget), submenu);
+              g_object_unref (submenu);
+            }
+          else
+            g_assert (!submenu_widget);
+        }
+
+      g_free (label);
+    }
+
+  /* If we found a separator but visited no children then the separator
+   * was not for us.  Patch that up.
+   */
+  if (has_separator && our_children == (*children)->next)
+    {
+      /* Rewind our_children to put the separator we tentatively
+       * consumed back into the list.
+       */
+      our_children = *children;
+      has_separator = FALSE;
+    }
+
+  if (our_children == *children)
+    /* If we had no children then we didn't really need a separator. */
+    needs_separator = FALSE;
+
+  g_assert (needs_separator == has_separator);
+
+  if (has_separator)
+    {
+      GtkWidget *contents;
+      const gchar *label;
+
+      /* We needed and had a separator and we visited a child.
+       *
+       * Make sure that separator was valid.
+       */
+      contents = gtk_bin_get_child ((*children)->data);
+      if (GTK_IS_LABEL (contents))
+        label = gtk_label_get_label (GTK_LABEL (contents));
+      else
+        label = "";
+
+      /* get_label() returns "" when it ought to return NULL */
+      g_assert_cmpstr (label, ==, section_header ? section_header : "");
+
+      /* our_children has already gone (possibly far) past *children, so
+       * we need to free up the link that we left behind for the
+       * separator in case we wanted to rewind.
+       */
+      g_slist_free_1 (*children);
+    }
+
+  *children = our_children;
+}
+
+/* We want to use a GSList here instead of a GList because the ->prev
+ * pointer updates cause trouble with the way we speculatively deal with
+ * separators by skipping over them and coming back to clean up later.
+ */
+static void
+get_children_into_slist (GtkWidget *widget,
+                         gpointer   user_data)
+{
+  GSList **list_ptr = user_data;
+
+  *list_ptr = g_slist_prepend (*list_ptr, widget);
+}
+
+static void
+assert_menu_equality (GtkContainer *container,
+                      GMenuModel   *model)
+{
+  GSList *children = NULL;
+
+  gtk_container_foreach (container, get_children_into_slist, &children);
+  children = g_slist_reverse (children);
+
+  assert_section_equality (&children, TRUE, FALSE, NULL, model);
+  g_assert (children == NULL);
+}
+
+static void
+test_bind_menu (void)
+{
+  RandomMenu *model;
+  GtkWidget *menu;
+  GRand *rand;
+  gint i;
+
+  gtk_init (0, 0);
+
+  rand = g_rand_new_with_seed (g_test_rand_int ());
+  model = random_menu_new (rand, TOP_ORDER);
+  menu = gtk_menu_new_from_model (G_MENU_MODEL (model));
+  g_object_ref_sink (menu);
+  assert_menu_equality (GTK_CONTAINER (menu), G_MENU_MODEL (model));
+  for (i = 0; i < 100; i++)
+    {
+      random_menu_change (model, rand);
+      while (g_main_context_iteration (NULL, FALSE));
+      assert_menu_equality (GTK_CONTAINER (menu), G_MENU_MODEL (model));
+    }
+  g_object_unref (model);
+  g_object_unref (menu);
+  g_rand_free (rand);
+}
+/* Epilogue {{{1 */
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/gmenu/bind", test_bind_menu);
+
+  return g_test_run ();
+}
+/* vim:set foldmethod=marker: */
diff --git a/testsuite/gtk/gtktreemodelrefcount.c b/testsuite/gtk/gtktreemodelrefcount.c
new file mode 100644 (file)
index 0000000..7f29f99
--- /dev/null
@@ -0,0 +1,313 @@
+/* gtktreemodelrefcount.c
+ * Copyright (C) 2011  Kristian Rietveld <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "gtktreemodelrefcount.h"
+
+
+/* The purpose of this GtkTreeModel is to keep record of the reference count
+ * of each node.  The reference count does not effect the functioning of
+ * the model in any way.  Because this model is a subclass of GtkTreeStore,
+ * the GtkTreeStore API should be used to add to and remove nodes from
+ * this model.  We depend on the iter format of GtkTreeStore, which means
+ * that this model needs to be revised in case the iter format of
+ * GtkTreeStore is modified.  Currently, we make use of the fact that
+ * the value stored in the user_data field is unique for each node.
+ */
+
+struct _GtkTreeModelRefCountPrivate
+{
+  GHashTable *node_hash;
+};
+
+typedef struct
+{
+  int ref_count;
+}
+NodeInfo;
+
+
+static void      gtk_tree_model_ref_count_tree_model_init (GtkTreeModelIface *iface);
+static void      gtk_tree_model_ref_count_finalize        (GObject           *object);
+
+static NodeInfo *node_info_new                            (void);
+static void      node_info_free                           (NodeInfo          *info);
+
+/* GtkTreeModel interface */
+static void      gtk_tree_model_ref_count_ref_node        (GtkTreeModel      *model,
+                                                           GtkTreeIter       *iter);
+static void      gtk_tree_model_ref_count_unref_node      (GtkTreeModel      *model,
+                                                           GtkTreeIter       *iter);
+
+
+G_DEFINE_TYPE_WITH_CODE (GtkTreeModelRefCount, gtk_tree_model_ref_count, GTK_TYPE_TREE_STORE,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
+                                                gtk_tree_model_ref_count_tree_model_init))
+
+static void
+row_removed (GtkTreeModelRefCount *ref_model,
+             GtkTreePath *path)
+{
+  GHashTableIter iter;
+  GtkTreeIter tree_iter;
+
+  if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ref_model), &tree_iter))
+    {
+      g_hash_table_remove_all (ref_model->priv->node_hash);
+      return;
+    }
+
+  g_hash_table_iter_init (&iter, ref_model->priv->node_hash);
+
+  while (g_hash_table_iter_next (&iter, &tree_iter.user_data, NULL))
+    {
+      if (!gtk_tree_store_iter_is_valid (GTK_TREE_STORE (ref_model), &tree_iter))
+        g_hash_table_iter_remove (&iter);
+    }
+}
+
+static void
+gtk_tree_model_ref_count_init (GtkTreeModelRefCount *ref_model)
+{
+  ref_model->priv = G_TYPE_INSTANCE_GET_PRIVATE (ref_model,
+                                                 GTK_TYPE_TREE_MODEL_REF_COUNT,
+                                                 GtkTreeModelRefCountPrivate);
+
+  ref_model->priv->node_hash = g_hash_table_new_full (g_direct_hash,
+                                                      g_direct_equal,
+                                                      NULL,
+                                                      (GDestroyNotify)node_info_free);
+
+  g_signal_connect (ref_model, "row-deleted", G_CALLBACK (row_removed), NULL);
+}
+
+static void
+gtk_tree_model_ref_count_class_init (GtkTreeModelRefCountClass *ref_model_class)
+{
+  GObjectClass *object_class;
+
+  object_class = (GObjectClass *) ref_model_class;
+
+  object_class->finalize = gtk_tree_model_ref_count_finalize;
+
+  g_type_class_add_private (object_class, sizeof (GtkTreeModelRefCountPrivate));
+}
+
+static void
+gtk_tree_model_ref_count_tree_model_init (GtkTreeModelIface *iface)
+{
+  iface->ref_node = gtk_tree_model_ref_count_ref_node;
+  iface->unref_node = gtk_tree_model_ref_count_unref_node;
+}
+
+static void
+gtk_tree_model_ref_count_finalize (GObject *object)
+{
+  GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (object);
+
+  if (ref_model->priv->node_hash)
+    {
+      g_hash_table_destroy (ref_model->priv->node_hash);
+      ref_model->priv->node_hash = NULL;
+    }
+
+  G_OBJECT_CLASS (gtk_tree_model_ref_count_parent_class)->finalize (object);
+}
+
+
+static NodeInfo *
+node_info_new (void)
+{
+  NodeInfo *info = g_slice_new (NodeInfo);
+  info->ref_count = 0;
+
+  return info;
+}
+
+static void
+node_info_free (NodeInfo *info)
+{
+  g_slice_free (NodeInfo, info);
+}
+
+static void
+gtk_tree_model_ref_count_ref_node (GtkTreeModel *model,
+                                   GtkTreeIter  *iter)
+{
+  NodeInfo *info;
+  GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
+  if (!info)
+    {
+      info = node_info_new ();
+
+      g_hash_table_insert (ref_model->priv->node_hash, iter->user_data, info);
+    }
+
+  info->ref_count++;
+}
+
+static void
+gtk_tree_model_ref_count_unref_node (GtkTreeModel *model,
+                                     GtkTreeIter  *iter)
+{
+  NodeInfo *info;
+  GtkTreeModelRefCount *ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
+  g_assert (info != NULL);
+  g_assert (info->ref_count > 0);
+
+  info->ref_count--;
+}
+
+
+GtkTreeModel *
+gtk_tree_model_ref_count_new (void)
+{
+  GtkTreeModel *retval;
+
+  retval = g_object_new (gtk_tree_model_ref_count_get_type (), NULL);
+
+  return retval;
+}
+
+static void
+dump_iter (GtkTreeModelRefCount *ref_model,
+           GtkTreeIter          *iter)
+{
+  gchar *path_str;
+  NodeInfo *info;
+  GtkTreePath *path;
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (ref_model), iter);
+  path_str = gtk_tree_path_to_string (path);
+  gtk_tree_path_free (path);
+
+  info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
+  if (!info)
+    g_print ("%-16s ref_count=0\n", path_str);
+  else
+    g_print ("%-16s ref_count=%d\n", path_str, info->ref_count);
+
+  g_free (path_str);
+}
+
+static void
+gtk_tree_model_ref_count_dump_recurse (GtkTreeModelRefCount *ref_model,
+                                       GtkTreeIter          *iter)
+{
+  do
+    {
+      GtkTreeIter child;
+
+      dump_iter (ref_model, iter);
+
+      if (gtk_tree_model_iter_children (GTK_TREE_MODEL (ref_model),
+                                        &child, iter))
+        gtk_tree_model_ref_count_dump_recurse (ref_model, &child);
+    }
+  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ref_model), iter));
+}
+
+void
+gtk_tree_model_ref_count_dump (GtkTreeModelRefCount *ref_model)
+{
+  GtkTreeIter iter;
+
+  if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ref_model), &iter))
+    return;
+
+  gtk_tree_model_ref_count_dump_recurse (ref_model, &iter);
+}
+
+static gboolean
+check_iter (GtkTreeModelRefCount *ref_model,
+            GtkTreeIter          *iter,
+            gint                  expected_ref_count,
+            gboolean              may_assert)
+{
+  NodeInfo *info;
+
+  if (may_assert)
+    g_assert (gtk_tree_store_iter_is_valid (GTK_TREE_STORE (ref_model), iter));
+
+  info = g_hash_table_lookup (ref_model->priv->node_hash, iter->user_data);
+  if (!info)
+    {
+      if (expected_ref_count == 0)
+        return TRUE;
+      else
+        {
+          if (may_assert)
+            g_error ("Expected ref count %d, but node has never been referenced.\n", expected_ref_count);
+          return FALSE;
+        }
+    }
+
+  if (may_assert)
+    {
+      if (expected_ref_count == 0)
+        g_assert_cmpint (expected_ref_count, ==, info->ref_count);
+      else
+        g_assert_cmpint (expected_ref_count, <=, info->ref_count);
+    }
+
+  return expected_ref_count == info->ref_count;
+}
+
+gboolean
+gtk_tree_model_ref_count_check_level (GtkTreeModelRefCount *ref_model,
+                                      GtkTreeIter          *parent,
+                                      gint                  expected_ref_count,
+                                      gboolean              recurse,
+                                      gboolean              may_assert)
+{
+  GtkTreeIter iter;
+
+  if (!gtk_tree_model_iter_children (GTK_TREE_MODEL (ref_model),
+                                     &iter, parent))
+    return TRUE;
+
+  do
+    {
+      if (!check_iter (ref_model, &iter, expected_ref_count, may_assert))
+        return FALSE;
+
+      if (recurse &&
+          gtk_tree_model_iter_has_child (GTK_TREE_MODEL (ref_model), &iter))
+        {
+          if (!gtk_tree_model_ref_count_check_level (ref_model, &iter,
+                                                     expected_ref_count,
+                                                     recurse, may_assert))
+            return FALSE;
+        }
+    }
+  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ref_model), &iter));
+
+  return TRUE;
+}
+
+gboolean
+gtk_tree_model_ref_count_check_node (GtkTreeModelRefCount *ref_model,
+                                     GtkTreeIter          *iter,
+                                     gint                  expected_ref_count,
+                                     gboolean              may_assert)
+{
+  return check_iter (ref_model, iter, expected_ref_count, may_assert);
+}
diff --git a/testsuite/gtk/gtktreemodelrefcount.h b/testsuite/gtk/gtktreemodelrefcount.h
new file mode 100644 (file)
index 0000000..a4b4011
--- /dev/null
@@ -0,0 +1,132 @@
+/* gtktreemodelrefcount.h
+ * Copyright (C) 2011  Kristian Rietveld <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_TREE_MODEL_REF_COUNT_H__
+#define __GTK_TREE_MODEL_REF_COUNT_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_TREE_MODEL_REF_COUNT              (gtk_tree_model_ref_count_get_type ())
+#define GTK_TREE_MODEL_REF_COUNT(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCount))
+#define GTK_TREE_MODEL_REF_COUNT_CLASS(vtable)     (G_TYPE_CHECK_CLASS_CAST ((vtable), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCountClass))
+#define GTK_IS_TREE_MODEL_REF_COUNT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT))
+#define GTK_IS_TREE_MODEL_REF_COUNT_CLASS(vtable)  (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_TYPE_TREE_MODEL_REF_COUNT))
+#define GTK_TREE_MODEL_REF_COUNT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TREE_MODEL_REF_COUNT, GtkTreeModelRefCountClass))
+
+
+typedef struct _GtkTreeModelRefCount        GtkTreeModelRefCount;
+typedef struct _GtkTreeModelRefCountClass   GtkTreeModelRefCountClass;
+typedef struct _GtkTreeModelRefCountPrivate GtkTreeModelRefCountPrivate;
+
+struct _GtkTreeModelRefCount
+{
+  GtkTreeStore parent;
+
+  /* < private > */
+  GtkTreeModelRefCountPrivate *priv;
+};
+
+struct _GtkTreeModelRefCountClass
+{
+  GtkTreeStoreClass parent_class;
+};
+
+
+GType         gtk_tree_model_ref_count_get_type    (void) G_GNUC_CONST;
+GtkTreeModel *gtk_tree_model_ref_count_new         (void);
+
+void          gtk_tree_model_ref_count_dump        (GtkTreeModelRefCount *ref_model);
+gboolean      gtk_tree_model_ref_count_check_level (GtkTreeModelRefCount *ref_model,
+                                                    GtkTreeIter          *parent,
+                                                    gint                  expected_ref_count,
+                                                    gboolean              recurse,
+                                                    gboolean              may_assert);
+gboolean      gtk_tree_model_ref_count_check_node  (GtkTreeModelRefCount *ref_model,
+                                                    GtkTreeIter          *iter,
+                                                    gint                  expected_ref_count,
+                                                    gboolean              may_assert);
+
+/* A couple of helpers for the tests.  Since this model will never be used
+ * outside of unit tests anyway, it is probably fine to have these here
+ * without namespacing.
+ */
+
+static inline void
+assert_entire_model_unreferenced (GtkTreeModelRefCount *ref_model)
+{
+  gtk_tree_model_ref_count_check_level (ref_model, NULL, 0, TRUE, TRUE);
+}
+
+static inline void
+assert_root_level_unreferenced (GtkTreeModelRefCount *ref_model)
+{
+  gtk_tree_model_ref_count_check_level (ref_model, NULL, 0, FALSE, TRUE);
+}
+
+static inline void
+assert_level_unreferenced (GtkTreeModelRefCount *ref_model,
+                           GtkTreeIter          *iter)
+{
+  gtk_tree_model_ref_count_check_level (ref_model, iter, 0, FALSE, TRUE);
+}
+
+static inline void
+assert_entire_model_referenced (GtkTreeModelRefCount *ref_model,
+                                gint                  ref_count)
+{
+  gtk_tree_model_ref_count_check_level (ref_model, NULL, ref_count, TRUE, TRUE);
+}
+
+static inline void
+assert_not_entire_model_referenced (GtkTreeModelRefCount *ref_model,
+                                    gint                  ref_count)
+{
+  g_assert_cmpint (gtk_tree_model_ref_count_check_level (ref_model, NULL,
+                                                         ref_count,
+                                                         TRUE, FALSE),
+                   ==, FALSE);
+}
+
+static inline void
+assert_root_level_referenced (GtkTreeModelRefCount *ref_model,
+                              gint                  ref_count)
+{
+  gtk_tree_model_ref_count_check_level (ref_model, NULL, ref_count,
+                                        FALSE, TRUE);
+}
+
+static inline void
+assert_level_referenced (GtkTreeModelRefCount *ref_model,
+                         gint                  ref_count,
+                         GtkTreeIter          *iter)
+{
+  gtk_tree_model_ref_count_check_level (ref_model, iter, ref_count,
+                                        FALSE, TRUE);
+}
+
+static inline void
+assert_node_ref_count (GtkTreeModelRefCount *ref_model,
+                       GtkTreeIter          *iter,
+                       gint                  ref_count)
+{
+  gtk_tree_model_ref_count_check_node (ref_model, iter, ref_count, TRUE);
+}
+
+
+#endif /* __GTK_TREE_MODEL_REF_COUNT_H__ */
diff --git a/testsuite/gtk/keyhash.c b/testsuite/gtk/keyhash.c
new file mode 100644 (file)
index 0000000..5bca1de
--- /dev/null
@@ -0,0 +1,203 @@
+/* keyhash.c
+ * Copyright (C) 2012 Red Hat, Inc12 Red Hat, Inc
+ * Authors: Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "../../gtk/gtkkeyhash.h"
+#include "../../gtk/gtkprivate.h"
+
+static gint count;
+
+static void
+counting_destroy (gpointer data)
+{
+  count++;
+}
+
+static void
+test_basic (void)
+{
+  GtkKeyHash *hash;
+  GSList *keys;
+
+  count = 0;
+  hash = _gtk_key_hash_new (gdk_keymap_get_default (), counting_destroy);
+
+  keys = _gtk_key_hash_lookup (hash, 0, 0, 0, 0);
+  g_assert (keys == NULL);
+
+  _gtk_key_hash_add_entry (hash, 1, 0, NULL);
+  _gtk_key_hash_add_entry (hash, 1, 1, NULL);
+  _gtk_key_hash_add_entry (hash, 2, 0, NULL);
+  _gtk_key_hash_add_entry (hash, 3, 0, NULL);
+  _gtk_key_hash_add_entry (hash, 4, 0, NULL);
+
+  _gtk_key_hash_free (hash);
+
+  g_assert_cmpint (count, ==, 5);
+}
+
+
+#if 0
+typedef struct
+{
+  guint           keyval;
+  GdkModifierType modifiers;
+} Entry;
+
+static void
+test_lookup (GtkKeyHash      *hash,
+             guint            keyval,
+             GdkModifierType  modifiers,
+             GdkModifierType  mask,
+             gint             n_results,
+             ...)
+{
+  va_list ap;
+  gint d;
+  GSList *res, *l;
+  gint i;
+  GdkKeymapKey *keys;
+  gint n_keys;
+
+  gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (), keyval, &keys, &n_keys);
+  if (n_keys == 0)
+    return;
+
+  res = _gtk_key_hash_lookup (hash, keys[0].keycode, modifiers, mask, keys[0].group);
+  g_free (keys);
+
+  g_assert_cmpint (g_slist_length (res), ==, n_results);
+
+  va_start (ap, n_results);
+  for (i = 0, l = res; i < n_results; i++, l = l->next)
+    {
+      d = va_arg (ap, int);
+      g_assert_cmpint (d, ==, GPOINTER_TO_INT (l->data));
+    }
+  va_end (ap);
+
+  g_slist_free (res);
+}
+
+static void
+add_entries (GtkKeyHash *hash,
+             Entry      *entries)
+{
+  gint i;
+
+  for (i = 0; entries[i].keyval; i++)
+    _gtk_key_hash_add_entry (hash, entries[i].keyval, entries[i].modifiers, GINT_TO_POINTER (i+1));
+}
+
+#define DEFAULT_MASK (GDK_CONTROL_MASK \
+                      | GDK_SHIFT_MASK \
+                      | GDK_MOD1_MASK  \
+                      | GDK_SUPER_MASK \
+                      | GDK_HYPER_MASK \
+                      | GDK_META_MASK)
+
+static void
+test_match (void)
+{
+  GtkKeyHash *hash;
+  static Entry entries[] = {
+    { GDK_KEY_a, GDK_CONTROL_MASK },
+    { GDK_KEY_a, GDK_CONTROL_MASK|GDK_SHIFT_MASK } ,
+    { GDK_KEY_b, GDK_MOD1_MASK|GDK_CONTROL_MASK },
+    { GDK_KEY_F10, 0 },
+    {  0, 0 }
+  };
+
+  hash = _gtk_key_hash_new (gdk_keymap_get_default (), NULL);
+  add_entries (hash, entries);
+
+  test_lookup (hash, GDK_KEY_a, GDK_CONTROL_MASK, DEFAULT_MASK, 4, 1, 1, 2, 2);
+  test_lookup (hash, GDK_KEY_A, GDK_CONTROL_MASK, DEFAULT_MASK, 4, 1, 1, 2, 2);
+  test_lookup (hash, GDK_KEY_a, GDK_MOD1_MASK, DEFAULT_MASK, 0);
+  test_lookup (hash, GDK_KEY_F10, 0, DEFAULT_MASK, 4, 4, 4, 4, 4);
+  test_lookup (hash, GDK_KEY_F10, GDK_SHIFT_MASK, DEFAULT_MASK, 4, 4, 4, 4, 4);
+
+  _gtk_key_hash_free (hash);
+}
+
+static gboolean
+hyper_equals_super (void)
+{
+  GdkModifierType mods1, mods2;
+
+  mods1 = GDK_HYPER_MASK;
+  gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods1);
+  mods1 = mods1 & ~GDK_HYPER_MASK;
+  mods2 = GDK_SUPER_MASK;
+  gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods2);
+  mods2 = mods2 & ~GDK_SUPER_MASK;
+
+  return mods1 == mods2;
+}
+
+static void
+test_virtual (void)
+{
+  GtkKeyHash *hash;
+  static Entry entries[] = {
+    { GDK_KEY_a, GDK_SUPER_MASK },
+    { GDK_KEY_b, GDK_HYPER_MASK } ,
+    { GDK_KEY_c, GDK_META_MASK },
+    { GDK_KEY_d, GDK_SUPER_MASK|GDK_HYPER_MASK },
+    {  0, 0 }
+  };
+
+  hash = _gtk_key_hash_new (gdk_keymap_get_default (), NULL);
+  add_entries (hash, entries);
+
+  test_lookup (hash, GDK_KEY_a, GDK_SUPER_MASK, DEFAULT_MASK, 2, 1, 1);
+  test_lookup (hash, GDK_KEY_a, GDK_HYPER_MASK, DEFAULT_MASK, 0);
+  test_lookup (hash, GDK_KEY_b, GDK_HYPER_MASK, DEFAULT_MASK, 2, 2, 2);
+  test_lookup (hash, GDK_KEY_c, GDK_META_MASK,  DEFAULT_MASK, 2, 3, 3);
+  if (hyper_equals_super ())
+    {
+      GdkModifierType mods;
+
+      /* test that colocated virtual modifiers don't count twice */
+      test_lookup (hash, GDK_KEY_d, GDK_SUPER_MASK, DEFAULT_MASK, 0);
+      test_lookup (hash, GDK_KEY_d, GDK_HYPER_MASK, DEFAULT_MASK, 0);
+
+      mods = GDK_HYPER_MASK;
+      gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mods);
+      test_lookup (hash, GDK_KEY_d, mods, DEFAULT_MASK, 0);
+    }
+
+  _gtk_key_hash_free (hash);
+}
+#endif
+
+int
+main (int argc, char **argv)
+{
+  /* initialize test program */
+  gtk_test_init (&argc, &argv);
+
+  g_test_add_func ("/keyhash/basic", test_basic);
+#if 0
+  /* FIXME: need to make these independent of xkb configuration */
+  g_test_add_func ("/keyhash/match", test_match);
+  g_test_add_func ("/keyhash/virtual", test_virtual);
+#endif
+  return g_test_run();
+}
diff --git a/testsuite/gtk/liststore.c b/testsuite/gtk/liststore.c
new file mode 100644 (file)
index 0000000..4455a13
--- /dev/null
@@ -0,0 +1,1139 @@
+/* Extensive GtkListStore tests.
+ * Copyright (C) 2007  Imendio AB
+ * Authors: Kristian Rietveld  <kris@imendio.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* To do:
+ *  - Test implementations of the interfaces: DnD, sortable, buildable
+ *    and the tree model interface itself?
+ *  - Need to check if the emitted signals are right.
+ *  - Needs analysis with the code coverage tool once it is there.
+ */
+
+#include <gtk/gtk.h>
+
+#include "treemodel.h"
+
+static inline gboolean
+iters_equal (GtkTreeIter *a,
+            GtkTreeIter *b)
+{
+  if (a->stamp != b->stamp)
+    return FALSE;
+
+  if (a->user_data != b->user_data)
+    return FALSE;
+
+  /* user_data2 and user_data3 are not used in GtkListStore */
+
+  return TRUE;
+}
+
+static gboolean
+iter_position (GtkListStore *store,
+              GtkTreeIter  *iter,
+              int           n)
+{
+  gboolean ret = TRUE;
+  GtkTreePath *path;
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
+  if (!path)
+    return FALSE;
+
+  if (gtk_tree_path_get_indices (path)[0] != n)
+    ret = FALSE;
+
+  gtk_tree_path_free (path);
+
+  return ret;
+}
+
+/*
+ * Fixture
+ */
+typedef struct
+{
+  GtkTreeIter iter[5];
+  GtkListStore *store;
+} ListStore;
+
+static void
+list_store_setup (ListStore     *fixture,
+                 gconstpointer  test_data)
+{
+  int i;
+
+  fixture->store = gtk_list_store_new (1, G_TYPE_INT);
+
+  for (i = 0; i < 5; i++)
+    {
+      gtk_list_store_insert (fixture->store, &fixture->iter[i], i);
+      gtk_list_store_set (fixture->store, &fixture->iter[i], 0, i, -1);
+    }
+}
+
+static void
+list_store_teardown (ListStore     *fixture,
+                    gconstpointer  test_data)
+{
+  g_object_unref (fixture->store);
+}
+
+/*
+ * The actual tests.
+ */
+
+static void
+check_model (ListStore *fixture,
+            gint      *new_order,
+            gint       skip)
+{
+  int i;
+  GtkTreePath *path;
+
+  path = gtk_tree_path_new ();
+  gtk_tree_path_down (path);
+
+  /* Check validity of the model and validity of the iters-persistent
+   * claim.
+   */
+  for (i = 0; i < 5; i++)
+    {
+      GtkTreeIter iter;
+
+      if (i == skip)
+       continue;
+
+      /* The saved iterator at new_order[i] should match the iterator
+       * at i.
+       */
+
+      gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+                              &iter, path);
+
+      g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter));
+      g_assert (iters_equal (&iter, &fixture->iter[new_order[i]]));
+
+      gtk_tree_path_next (path);
+    }
+
+  gtk_tree_path_free (path);
+}
+
+/* insertion */
+static void
+list_store_test_insert_high_values (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  gtk_list_store_insert (store, &iter, 1234);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  gtk_list_store_insert (store, &iter2, 765);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+list_store_test_append (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  gtk_list_store_append (store, &iter);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  gtk_list_store_append (store, &iter2);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+list_store_test_prepend (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  gtk_list_store_prepend (store, &iter);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  gtk_list_store_prepend (store, &iter2);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+list_store_test_insert_after (void)
+{
+  GtkTreeIter iter, iter2, iter3;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_append (store, &iter2);
+
+  gtk_list_store_insert_after (store, &iter3, &iter);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter3));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 1));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 2));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 2));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+list_store_test_insert_after_NULL (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  gtk_list_store_append (store, &iter);
+
+  /* move_after NULL is basically a prepend */
+  gtk_list_store_insert_after (store, &iter2, NULL);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
+  g_assert (iters_equal (&iter2, &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+list_store_test_insert_before (void)
+{
+  GtkTreeIter iter, iter2, iter3;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_append (store, &iter2);
+
+  gtk_list_store_insert_before (store, &iter3, &iter2);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter3));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 1));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 2));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter3, &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 2));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+list_store_test_insert_before_NULL (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  gtk_list_store_append (store, &iter);
+
+  /* move_before NULL is basically an append */
+  gtk_list_store_insert_before (store, &iter2, NULL);
+  g_assert (gtk_list_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+/* setting values */
+static void
+list_store_set_gvalue_to_transform (void)
+{
+  GtkListStore *store;
+  GtkTreeIter iter;
+  GValue value = G_VALUE_INIT;
+
+  /* https://bugzilla.gnome.org/show_bug.cgi?id=677649 */
+  store = gtk_list_store_new (1, G_TYPE_LONG);
+  gtk_list_store_append (store, &iter);
+
+  g_value_init (&value, G_TYPE_INT);
+  g_value_set_int (&value, 42);
+  gtk_list_store_set_value (store, &iter, 0, &value);
+}
+
+/* removal */
+static void
+list_store_test_remove_begin (ListStore     *fixture,
+                             gconstpointer  user_data)
+{
+  int new_order[5] = { -1, 1, 2, 3, 4 };
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  /* Remove node at 0 */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+  gtk_tree_path_free (path);
+
+  g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
+  g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[0]));
+  g_assert (iters_equal (&iter, &fixture->iter[1]));
+
+  check_model (fixture, new_order, 0);
+}
+
+static void
+list_store_test_remove_middle (ListStore     *fixture,
+                              gconstpointer  user_data)
+{
+  int new_order[5] = { 0, 1, -1, 3, 4 };
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  /* Remove node at 2 */
+  path = gtk_tree_path_new_from_indices (2, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+  gtk_tree_path_free (path);
+
+  g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
+  g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[2]));
+  g_assert (iters_equal (&iter, &fixture->iter[3]));
+
+  check_model (fixture, new_order, 2);
+}
+
+static void
+list_store_test_remove_end (ListStore     *fixture,
+                           gconstpointer  user_data)
+{
+  int new_order[5] = { 0, 1, 2, 3, -1 };
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  /* Remove node at 4 */
+  path = gtk_tree_path_new_from_indices (4, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+  gtk_tree_path_free (path);
+
+  g_assert (gtk_list_store_remove (fixture->store, &iter) == FALSE);
+  g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[4]));
+
+  check_model (fixture, new_order, 4);
+}
+
+static void
+list_store_test_clear (ListStore     *fixture,
+                      gconstpointer  user_data)
+{
+  int i;
+
+  gtk_list_store_clear (fixture->store);
+
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL) == 0);
+
+  for (i = 0; i < 5; i++)
+    g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[i]));
+}
+
+/* reorder */
+
+static void
+list_store_test_reorder (ListStore     *fixture,
+                        gconstpointer  user_data)
+{
+  int new_order[5] = { 4, 1, 0, 2, 3 };
+
+  gtk_list_store_reorder (fixture->store, new_order);
+  check_model (fixture, new_order, -1);
+}
+
+/* swapping */
+
+static void
+list_store_test_swap_begin (ListStore     *fixture,
+                           gconstpointer  user_data)
+{
+  /* We swap nodes 0 and 1 at the beginning */
+  int new_order[5] = { 1, 0, 2, 3, 4 };
+
+  GtkTreeIter iter_a;
+  GtkTreeIter iter_b;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
+
+  gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_swap_middle_next (ListStore     *fixture,
+                                 gconstpointer  user_data)
+{
+  /* We swap nodes 2 and 3 in the middle that are next to each other */
+  int new_order[5] = { 0, 1, 3, 2, 4 };
+
+  GtkTreeIter iter_a;
+  GtkTreeIter iter_b;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "2"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
+
+  gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_swap_middle_apart (ListStore     *fixture,
+                                  gconstpointer  user_data)
+{
+  /* We swap nodes 1 and 3 in the middle that are apart from each other */
+  int new_order[5] = { 0, 3, 2, 1, 4 };
+
+  GtkTreeIter iter_a;
+  GtkTreeIter iter_b;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "1"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
+
+  gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_swap_end (ListStore     *fixture,
+                         gconstpointer  user_data)
+{
+  /* We swap nodes 3 and 4 at the end */
+  int new_order[5] = { 0, 1, 2, 4, 3 };
+
+  GtkTreeIter iter_a;
+  GtkTreeIter iter_b;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "3"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
+
+  gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_swap_single (void)
+{
+  GtkTreeIter iter;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  /* Check if swap on a store with a single node does not corrupt
+   * the store.
+   */
+
+  gtk_list_store_append (store, &iter);
+  iter_copy = iter;
+
+  gtk_list_store_swap (store, &iter, &iter);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  g_object_unref (store);
+}
+
+/* move after */
+
+static void
+list_store_test_move_after_from_start (ListStore     *fixture,
+                                      gconstpointer  user_data)
+{
+  /* We move node 0 after 2 */
+  int new_order[5] = { 1, 2, 0, 3, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
+
+  gtk_list_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_after_next (ListStore     *fixture,
+                                gconstpointer  user_data)
+{
+  /* We move node 2 after 3 */
+  int new_order[5] = { 0, 1, 3, 2, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
+
+  gtk_list_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_after_apart (ListStore     *fixture,
+                                 gconstpointer  user_data)
+{
+  /* We move node 1 after 3 */
+  int new_order[5] = { 0, 2, 3, 1, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
+
+  gtk_list_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_after_end (ListStore     *fixture,
+                               gconstpointer  user_data)
+{
+  /* We move node 2 after 4 */
+  int new_order[5] = { 0, 1, 3, 4, 2 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
+
+  gtk_list_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_after_from_end (ListStore     *fixture,
+                                    gconstpointer  user_data)
+{
+  /* We move node 4 after 1 */
+  int new_order[5] = { 0, 1, 4, 2, 3 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
+
+  gtk_list_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_after_change_ends (ListStore     *fixture,
+                                       gconstpointer  user_data)
+{
+  /* We move 0 after 4, this will cause both the head and tail ends to
+   * change.
+   */
+  int new_order[5] = { 1, 2, 3, 4, 0 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
+
+  gtk_list_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_after_NULL (ListStore     *fixture,
+                                gconstpointer  user_data)
+{
+  /* We move node 2, NULL should prepend */
+  int new_order[5] = { 2, 0, 1, 3, 4 };
+
+  GtkTreeIter iter;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+
+  gtk_list_store_move_after (fixture->store, &iter, NULL);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_after_single (void)
+{
+  GtkTreeIter iter;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  /* Check if move-after on a store with a single node does not corrupt
+   * the store.
+   */
+
+  gtk_list_store_append (store, &iter);
+  iter_copy = iter;
+
+  gtk_list_store_move_after (store, &iter, NULL);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  gtk_list_store_move_after (store, &iter, &iter);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  g_object_unref (store);
+}
+
+/* move before */
+
+static void
+list_store_test_move_before_next (ListStore     *fixture,
+                                 gconstpointer  user_data)
+{
+  /* We move node 3 before 2 */
+  int new_order[5] = { 0, 1, 3, 2, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
+
+  gtk_list_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_before_apart (ListStore     *fixture,
+                                  gconstpointer  user_data)
+{
+  /* We move node 1 before 3 */
+  int new_order[5] = { 0, 2, 1, 3, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
+
+  gtk_list_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_before_to_start (ListStore     *fixture,
+                                     gconstpointer  user_data)
+{
+  /* We move node 2 before 0 */
+  int new_order[5] = { 2, 0, 1, 3, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
+
+  gtk_list_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_before_from_end (ListStore     *fixture,
+                                     gconstpointer  user_data)
+{
+  /* We move node 4 before 2 (replace end) */
+  int new_order[5] = { 0, 1, 4, 2, 3 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
+
+  gtk_list_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_before_change_ends (ListStore     *fixture,
+                                        gconstpointer  user_data)
+{
+  /* We move node 4 before 0 */
+  int new_order[5] = { 4, 0, 1, 2, 3 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
+
+  gtk_list_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_before_NULL (ListStore     *fixture,
+                                 gconstpointer  user_data)
+{
+  /* We move node 2, NULL should append */
+  int new_order[5] = { 0, 1, 3, 4, 2 };
+
+  GtkTreeIter iter;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+
+  gtk_list_store_move_before (fixture->store, &iter, NULL);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+list_store_test_move_before_single (void)
+{
+  GtkTreeIter iter;
+  GtkTreeIter iter_copy;
+  GtkListStore *store;
+
+  store = gtk_list_store_new (1, G_TYPE_INT);
+
+  /* Check if move-before on a store with a single node does not corrupt
+   * the store.
+   */
+
+  gtk_list_store_append (store, &iter);
+  iter_copy = iter;
+
+  gtk_list_store_move_before (store, &iter, NULL);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  gtk_list_store_move_before (store, &iter, &iter);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  g_object_unref (store);
+}
+
+
+/* iter invalidation */
+
+static void
+list_store_test_iter_previous_invalid (ListStore     *fixture,
+                                       gconstpointer  user_data)
+{
+  GtkTreeIter iter;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
+                                          &iter) == FALSE);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
+  g_assert (iter.stamp == 0);
+}
+
+static void
+list_store_test_iter_next_invalid (ListStore     *fixture,
+                                   gconstpointer  user_data)
+{
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  path = gtk_tree_path_new_from_indices (4, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+  gtk_tree_path_free (path);
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
+                                      &iter) == FALSE);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
+  g_assert (iter.stamp == 0);
+}
+
+static void
+list_store_test_iter_children_invalid (ListStore     *fixture,
+                                       gconstpointer  user_data)
+{
+  GtkTreeIter iter, child;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
+
+  g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
+                                          &child, &iter) == FALSE);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
+  g_assert (child.stamp == 0);
+}
+
+static void
+list_store_test_iter_nth_child_invalid (ListStore     *fixture,
+                                        gconstpointer  user_data)
+{
+  GtkTreeIter iter, child;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
+                                           &child, &iter, 0) == FALSE);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
+  g_assert (child.stamp == 0);
+}
+
+static void
+list_store_test_iter_parent_invalid (ListStore     *fixture,
+                                     gconstpointer  user_data)
+{
+  GtkTreeIter iter, child;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == TRUE);
+
+  g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
+                                        &iter, &child) == FALSE);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
+  g_assert (iter.stamp == 0);
+}
+
+
+/* main */
+
+void
+register_list_store_tests (void)
+{
+  /* insertion */
+  g_test_add_func ("/ListStore/insert-high-values",
+                  list_store_test_insert_high_values);
+  g_test_add_func ("/ListStore/append",
+                  list_store_test_append);
+  g_test_add_func ("/ListStore/prepend",
+                  list_store_test_prepend);
+  g_test_add_func ("/ListStore/insert-after",
+                  list_store_test_insert_after);
+  g_test_add_func ("/ListStore/insert-after-NULL",
+                  list_store_test_insert_after_NULL);
+  g_test_add_func ("/ListStore/insert-before",
+                  list_store_test_insert_before);
+  g_test_add_func ("/ListStore/insert-before-NULL",
+                  list_store_test_insert_before_NULL);
+
+  /* setting values (FIXME) */
+  g_test_add_func ("/ListStore/set-gvalue-to-transform",
+                   list_store_set_gvalue_to_transform);
+
+  /* removal */
+  g_test_add ("/ListStore/remove-begin", ListStore, NULL,
+             list_store_setup, list_store_test_remove_begin,
+             list_store_teardown);
+  g_test_add ("/ListStore/remove-middle", ListStore, NULL,
+             list_store_setup, list_store_test_remove_middle,
+             list_store_teardown);
+  g_test_add ("/ListStore/remove-end", ListStore, NULL,
+             list_store_setup, list_store_test_remove_end,
+             list_store_teardown);
+
+  g_test_add ("/ListStore/clear", ListStore, NULL,
+             list_store_setup, list_store_test_clear,
+             list_store_teardown);
+
+  /* reordering */
+  g_test_add ("/ListStore/reorder", ListStore, NULL,
+             list_store_setup, list_store_test_reorder,
+             list_store_teardown);
+
+  /* swapping */
+  g_test_add ("/ListStore/swap-begin", ListStore, NULL,
+             list_store_setup, list_store_test_swap_begin,
+             list_store_teardown);
+  g_test_add ("/ListStore/swap-middle-next", ListStore, NULL,
+             list_store_setup, list_store_test_swap_middle_next,
+             list_store_teardown);
+  g_test_add ("/ListStore/swap-middle-apart", ListStore, NULL,
+             list_store_setup, list_store_test_swap_middle_apart,
+             list_store_teardown);
+  g_test_add ("/ListStore/swap-end", ListStore, NULL,
+             list_store_setup, list_store_test_swap_end,
+             list_store_teardown);
+  g_test_add_func ("/ListStore/swap-single",
+                  list_store_test_swap_single);
+
+  /* moving */
+  g_test_add ("/ListStore/move-after-from-start", ListStore, NULL,
+             list_store_setup, list_store_test_move_after_from_start,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-after-next", ListStore, NULL,
+             list_store_setup, list_store_test_move_after_next,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-after-apart", ListStore, NULL,
+             list_store_setup, list_store_test_move_after_apart,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-after-end", ListStore, NULL,
+             list_store_setup, list_store_test_move_after_end,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-after-from-end", ListStore, NULL,
+             list_store_setup, list_store_test_move_after_from_end,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-after-change-ends", ListStore, NULL,
+             list_store_setup, list_store_test_move_after_change_ends,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-after-NULL", ListStore, NULL,
+             list_store_setup, list_store_test_move_after_NULL,
+             list_store_teardown);
+  g_test_add_func ("/ListStore/move-after-single",
+                  list_store_test_move_after_single);
+
+  g_test_add ("/ListStore/move-before-next", ListStore, NULL,
+             list_store_setup, list_store_test_move_before_next,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-before-apart", ListStore, NULL,
+             list_store_setup, list_store_test_move_before_apart,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-before-to-start", ListStore, NULL,
+             list_store_setup, list_store_test_move_before_to_start,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-before-from-end", ListStore, NULL,
+             list_store_setup, list_store_test_move_before_from_end,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-before-change-ends", ListStore, NULL,
+             list_store_setup, list_store_test_move_before_change_ends,
+             list_store_teardown);
+  g_test_add ("/ListStore/move-before-NULL", ListStore, NULL,
+             list_store_setup, list_store_test_move_before_NULL,
+             list_store_teardown);
+  g_test_add_func ("/ListStore/move-before-single",
+                  list_store_test_move_before_single);
+
+  /* iter invalidation */
+  g_test_add ("/ListStore/iter-prev-invalid", ListStore, NULL,
+              list_store_setup, list_store_test_iter_previous_invalid,
+              list_store_teardown);
+  g_test_add ("/ListStore/iter-next-invalid", ListStore, NULL,
+              list_store_setup, list_store_test_iter_next_invalid,
+              list_store_teardown);
+  g_test_add ("/ListStore/iter-children-invalid", ListStore, NULL,
+              list_store_setup, list_store_test_iter_children_invalid,
+              list_store_teardown);
+  g_test_add ("/ListStore/iter-nth-child-invalid", ListStore, NULL,
+              list_store_setup, list_store_test_iter_nth_child_invalid,
+              list_store_teardown);
+  g_test_add ("/ListStore/iter-parent-invalid", ListStore, NULL,
+              list_store_setup, list_store_test_iter_parent_invalid,
+              list_store_teardown);
+}
diff --git a/testsuite/gtk/modelrefcount.c b/testsuite/gtk/modelrefcount.c
new file mode 100644 (file)
index 0000000..2d39d9c
--- /dev/null
@@ -0,0 +1,976 @@
+/* GtkTreeModel ref counting tests
+ * Copyright (C) 2011  Kristian Rietveld  <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gtktreemodelrefcount.h"
+#include "treemodel.h"
+
+/* And the tests themselves */
+
+static void
+test_list_no_reference (void)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+
+  assert_root_level_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_list_reference_during_creation (void)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_root_level_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_list_reference_after_creation (void)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  assert_root_level_unreferenced (ref_model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_root_level_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_list_reference_reordered (void)
+{
+  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  assert_root_level_unreferenced (ref_model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter3, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter4, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter5, NULL);
+
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  gtk_tree_store_move_after (GTK_TREE_STORE (model),
+                             &iter1, &iter5);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  gtk_tree_store_move_after (GTK_TREE_STORE (model),
+                             &iter3, &iter4);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_root_level_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+
+static void
+test_tree_no_reference (void)
+{
+  GtkTreeIter iter, child;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_tree_reference_during_creation (void)
+{
+  GtkTreeIter iter, child;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_not_entire_model_referenced (ref_model, 1);
+  assert_level_unreferenced (ref_model, &child);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_tree_reference_after_creation (void)
+{
+  GtkTreeIter iter, child;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_not_entire_model_referenced (ref_model, 1);
+  assert_level_unreferenced (ref_model, &child);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_tree_reference_reordered (void)
+{
+  GtkTreeIter parent;
+  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  assert_root_level_unreferenced (ref_model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, &parent);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, &parent);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter3, &parent);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter4, &parent);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter5, &parent);
+
+  tree_view = gtk_tree_view_new_with_model (model);
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  gtk_tree_store_move_after (GTK_TREE_STORE (model),
+                             &iter1, &iter5);
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  gtk_tree_store_move_after (GTK_TREE_STORE (model),
+                             &iter3, &iter4);
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_tree_reference_expand_all (void)
+{
+  GtkTreeIter iter, child;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_not_entire_model_referenced (ref_model, 1);
+  assert_level_unreferenced (ref_model, &child);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_not_entire_model_referenced (ref_model, 1);
+  assert_level_unreferenced (ref_model, &child);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_tree_reference_collapse_all (void)
+{
+  GtkTreeIter iter, child;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  tree_view = gtk_tree_view_new_with_model (model);
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_not_entire_model_referenced (ref_model, 1);
+  assert_level_unreferenced (ref_model, &child);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_tree_reference_expand_collapse (void)
+{
+  GtkTreeIter parent1, parent2, child;
+  GtkTreePath *path1, *path2;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent2);
+
+  path1 = gtk_tree_model_get_path (model, &parent1);
+  path2 = gtk_tree_model_get_path (model, &parent2);
+
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_unreferenced (ref_model, &parent2);
+
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path1, FALSE);
+
+  assert_level_referenced (ref_model, 1, &parent1);
+  assert_level_unreferenced (ref_model, &parent2);
+
+  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path1);
+
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_unreferenced (ref_model, &parent2);
+
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path2, FALSE);
+
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_referenced (ref_model, 1, &parent2);
+
+  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path2);
+
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_unreferenced (ref_model, &parent2);
+
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path2, FALSE);
+
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_referenced (ref_model, 1, &parent2);
+
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path1, FALSE);
+
+  assert_level_referenced (ref_model, 1, &parent1);
+  assert_level_referenced (ref_model, 1, &parent2);
+
+  gtk_tree_path_free (path1);
+  gtk_tree_path_free (path2);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (ref_model);
+}
+
+static void
+test_row_reference_list (void)
+{
+  GtkTreeIter iter0, iter1, iter2;
+  GtkTreePath *path;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeRowReference *row_ref;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
+
+  assert_root_level_unreferenced (ref_model);
+
+  /* create and remove a row ref and check reference counts */
+  path = gtk_tree_path_new_from_indices (1, -1);
+  row_ref = gtk_tree_row_reference_new (model, path);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &iter2, 0);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_root_level_unreferenced (ref_model);
+
+  /* the same, but then also with a tree view monitoring the model */
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  row_ref = gtk_tree_row_reference_new (model, path);
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &iter1, 2);
+  assert_node_ref_count (ref_model, &iter2, 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &iter2, 0);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_root_level_unreferenced (ref_model);
+
+  gtk_tree_path_free (path);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_row_reference_list_remove (void)
+{
+  GtkTreeIter iter0, iter1, iter2;
+  GtkTreePath *path;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeRowReference *row_ref;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
+
+  assert_root_level_unreferenced (ref_model);
+
+  /* test creating the row reference and then removing the node */
+  path = gtk_tree_path_new_from_indices (1, -1);
+  row_ref = gtk_tree_row_reference_new (model, path);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &iter2, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter1);
+
+  assert_root_level_unreferenced (ref_model);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_root_level_unreferenced (ref_model);
+
+  /* test creating a row ref, removing another node and then removing
+   * the row ref node.
+   */
+  row_ref = gtk_tree_row_reference_new (model, path);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &iter2, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter0);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
+
+  g_assert (!gtk_tree_model_get_iter_first (model, &iter0));
+
+  gtk_tree_row_reference_free (row_ref);
+
+  gtk_tree_path_free (path);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_row_reference_tree (void)
+{
+  GtkTreeIter iter0, iter1, iter2;
+  GtkTreeIter child0, child1, child2;
+  GtkTreeIter grandchild0, grandchild1, grandchild2;
+  GtkTreePath *path;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeRowReference *row_ref, *row_ref1;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  /* create and remove a row ref and check reference counts */
+  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
+  row_ref = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &grandchild1, 1);
+  assert_node_ref_count (ref_model, &iter2, 0);
+  assert_node_ref_count (ref_model, &child2, 0);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  /* again, with path 1:1 */
+  path = gtk_tree_path_new_from_indices (1, 0, -1);
+  row_ref = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &grandchild1, 0);
+  assert_node_ref_count (ref_model, &iter2, 0);
+  assert_node_ref_count (ref_model, &child2, 0);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  /* both row refs existent at once and also with a tree view monitoring
+   * the model
+   */
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
+  row_ref = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 2);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &grandchild1, 1);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &child2, 0);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  path = gtk_tree_path_new_from_indices (1, 0, -1);
+  row_ref1 = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 3);
+  assert_node_ref_count (ref_model, &child1, 2);
+  assert_node_ref_count (ref_model, &grandchild1, 1);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &child2, 0);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 2);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &grandchild1, 0);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &child2, 0);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &grandchild1, 0);
+  assert_node_ref_count (ref_model, &iter2, 0);
+  assert_node_ref_count (ref_model, &child2, 0);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_tree_row_reference_free (row_ref1);
+
+  assert_root_level_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_row_reference_tree_remove (void)
+{
+  GtkTreeIter iter0, iter1, iter2;
+  GtkTreeIter child0, child1, child2;
+  GtkTreeIter grandchild0, grandchild1, grandchild2;
+  GtkTreePath *path;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeRowReference *row_ref, *row_ref1, *row_ref2;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
+  row_ref = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (2, 0, -1);
+  row_ref1 = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (2, -1);
+  row_ref2 = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &grandchild1, 1);
+  assert_node_ref_count (ref_model, &iter2, 2);
+  assert_node_ref_count (ref_model, &child2, 1);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandchild1);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 0);
+  assert_node_ref_count (ref_model, &child1, 0);
+  assert_node_ref_count (ref_model, &iter2, 2);
+  assert_node_ref_count (ref_model, &child2, 1);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 0);
+  assert_node_ref_count (ref_model, &child1, 0);
+  assert_node_ref_count (ref_model, &iter2, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  gtk_tree_row_reference_free (row_ref);
+  gtk_tree_row_reference_free (row_ref1);
+  gtk_tree_row_reference_free (row_ref2);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_row_reference_tree_remove_ancestor (void)
+{
+  GtkTreeIter iter0, iter1, iter2;
+  GtkTreeIter child0, child1, child2;
+  GtkTreeIter grandchild0, grandchild1, grandchild2;
+  GtkTreePath *path;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeRowReference *row_ref, *row_ref1;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
+  row_ref = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (2, 0, -1);
+  row_ref1 = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &grandchild1, 1);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &child2, 1);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &child1);
+
+  assert_node_ref_count (ref_model, &iter0, 0);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 0);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &child2, 1);
+  assert_node_ref_count (ref_model, &grandchild2, 0);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  gtk_tree_row_reference_free (row_ref);
+  gtk_tree_row_reference_free (row_ref1);
+
+  g_object_unref (ref_model);
+}
+
+static void
+test_row_reference_tree_expand (void)
+{
+  GtkTreeIter iter0, iter1, iter2;
+  GtkTreeIter child0, child1, child2;
+  GtkTreeIter grandchild0, grandchild1, grandchild2;
+  GtkTreePath *path;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeRowReference *row_ref, *row_ref1, *row_ref2;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+  tree_view = gtk_tree_view_new_with_model (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
+
+  assert_root_level_referenced (ref_model, 1);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
+  row_ref = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (2, 0, -1);
+  row_ref1 = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  path = gtk_tree_path_new_from_indices (2, -1);
+  row_ref2 = gtk_tree_row_reference_new (model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &child0, 1);
+  assert_node_ref_count (ref_model, &grandchild0, 1);
+  assert_node_ref_count (ref_model, &iter1, 2);
+  assert_node_ref_count (ref_model, &child1, 2);
+  assert_node_ref_count (ref_model, &grandchild1, 2);
+  assert_node_ref_count (ref_model, &iter2, 3);
+  assert_node_ref_count (ref_model, &child2, 2);
+  assert_node_ref_count (ref_model, &grandchild2, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandchild1);
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &child0, 1);
+  assert_node_ref_count (ref_model, &grandchild0, 1);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &iter2, 3);
+  assert_node_ref_count (ref_model, &child2, 2);
+  assert_node_ref_count (ref_model, &grandchild2, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &child0, 1);
+  assert_node_ref_count (ref_model, &grandchild0, 1);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 1);
+  assert_node_ref_count (ref_model, &iter2, 2);
+
+  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 0);
+  assert_node_ref_count (ref_model, &iter2, 2);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
+
+  assert_node_ref_count (ref_model, &iter0, 1);
+  assert_node_ref_count (ref_model, &child0, 0);
+  assert_node_ref_count (ref_model, &grandchild0, 0);
+  assert_node_ref_count (ref_model, &iter1, 1);
+  assert_node_ref_count (ref_model, &child1, 0);
+
+  gtk_tree_row_reference_free (row_ref);
+  gtk_tree_row_reference_free (row_ref1);
+  gtk_tree_row_reference_free (row_ref2);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (ref_model);
+}
+
+void
+register_model_ref_count_tests (void)
+{
+  /* lists (though based on GtkTreeStore) */
+  g_test_add_func ("/TreeModel/ref-count/list/no-reference",
+                   test_list_no_reference);
+  g_test_add_func ("/TreeModel/ref-count/list/reference-during-creation",
+                   test_list_reference_during_creation);
+  g_test_add_func ("/TreeModel/ref-count/list/reference-after-creation",
+                   test_list_reference_after_creation);
+  g_test_add_func ("/TreeModel/ref-count/list/reference-reordered",
+                   test_list_reference_reordered);
+
+  /* trees */
+  g_test_add_func ("/TreeModel/ref-count/tree/no-reference",
+                   test_tree_no_reference);
+  g_test_add_func ("/TreeModel/ref-count/tree/reference-during-creation",
+                   test_tree_reference_during_creation);
+  g_test_add_func ("/TreeModel/ref-count/tree/reference-after-creation",
+                   test_tree_reference_after_creation);
+  g_test_add_func ("/TreeModel/ref-count/tree/expand-all",
+                   test_tree_reference_expand_all);
+  g_test_add_func ("/TreeModel/ref-count/tree/collapse-all",
+                   test_tree_reference_collapse_all);
+  g_test_add_func ("/TreeModel/ref-count/tree/expand-collapse",
+                   test_tree_reference_expand_collapse);
+  g_test_add_func ("/TreeModel/ref-count/tree/reference-reordered",
+                   test_tree_reference_reordered);
+
+  /* row references */
+  g_test_add_func ("/TreeModel/ref-count/row-reference/list",
+                   test_row_reference_list);
+  g_test_add_func ("/TreeModel/ref-count/row-reference/list-remove",
+                   test_row_reference_list_remove);
+  g_test_add_func ("/TreeModel/ref-count/row-reference/tree",
+                   test_row_reference_tree);
+  g_test_add_func ("/TreeModel/ref-count/row-reference/tree-remove",
+                   test_row_reference_tree_remove);
+  g_test_add_func ("/TreeModel/ref-count/row-reference/tree-remove-ancestor",
+                   test_row_reference_tree_remove_ancestor);
+  g_test_add_func ("/TreeModel/ref-count/row-reference/tree-expand",
+                   test_row_reference_tree_expand);
+}
diff --git a/testsuite/gtk/object.c b/testsuite/gtk/object.c
new file mode 100644 (file)
index 0000000..1e06ded
--- /dev/null
@@ -0,0 +1,329 @@
+/* Gtk+ object tests
+ * Copyright (C) 2007 Imendio AB
+ * Authors: Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <gtk/gtk.h>
+#include <string.h>
+
+/* --- helper macros for property value generation --- */
+/* dvalue=+0: generate minimum value
+ * dvalue=.x: generate value within value range proportional to x.
+ * dvalue=+1: generate maximum value
+ * dvalue=-1: generate random value within value range
+ * dvalue=+2: initialize value from default_value
+ */
+#define ASSIGN_VALUE(__g_value_set_func, __value, PSPECTYPE, __pspec, __default_value, __minimum, __maximum, __dvalue) do { \
+  PSPECTYPE __p = (PSPECTYPE) __pspec; \
+  __g_value_set_func (__value, SELECT_VALUE (__dvalue, __p->__default_value, __p->__minimum, __p->__maximum)); \
+} while (0)
+#define SELECT_VALUE(__dvalue, __default_value, __minimum, __maximum) ( \
+  __dvalue >= 0 && __dvalue <= 1 ? __minimum * (1 - __dvalue) + __dvalue * __maximum : \
+    __dvalue <= -1 ? g_test_rand_double_range (__minimum, __maximum) : \
+      __default_value)
+#define SELECT_NAME(__dvalue) ( \
+  __dvalue == 0 ? "minimum" : \
+    __dvalue == 1 ? "maximum" : \
+      __dvalue >= +2 ? "default" : \
+        __dvalue == 0.5 ? "medium" : \
+          __dvalue > 0 && __dvalue < 1 ? "fractional" : \
+            "random")
+#define MATCH_ANY_VALUE         ((void*) 0xf1874c23)
+
+/* --- property blacklists --- */
+typedef struct {
+  const char   *type_name;
+  const char   *name;
+  gconstpointer value;
+} IgnoreProperty;
+static const IgnoreProperty*
+list_ignore_properties (gboolean buglist)
+{
+  /* currently untestable properties */
+  static const IgnoreProperty ignore_properties[] = {
+    { "GtkContainer",           "child",                NULL, },                        /* needs working child widget */
+    { "GtkRadioMenuItem",       "group",                NULL, },                        /* needs working sibling */
+    { "GtkWidget",              "parent",               NULL, },                        /* needs working parent widget */
+    { "GtkCList",               "selection-mode",       (void*) GTK_SELECTION_NONE, },
+    { "GtkWidget",              "has-default",          (void*) TRUE, },                /* conflicts with toplevel-less widgets */
+    { "GtkWidget",              "screen",               NULL, },
+    { "GtkWindow",              "type-hint",            (void*) GDK_WINDOW_TYPE_HINT_DND, }, /* conflicts with ::visible=TRUE */
+    { "GtkCellView",            "background",           (void*) "", },                  /* "" is not a valid background color */
+    { "GtkColorButton",         "color",                (void*) NULL, },                /* not a valid boxed color */
+    { "GtkInputDialog",         "has-separator",        (void*) MATCH_ANY_VALUE, },     /* property disabled */
+    { "GtkMessageDialog",       "has-separator",        (void*) MATCH_ANY_VALUE, },     /* property disabled */
+    { "GtkFontSelectionDialog", "has-separator",        (void*) MATCH_ANY_VALUE, },     /* property disabled */
+    { "GtkColorSelectionDialog","has-separator",        (void*) MATCH_ANY_VALUE, },     /* property disabled */
+    { "GtkColorSelection",      "child",                NULL, },
+    { "GtkColorSelection",      "current-color",        (void*) NULL, },                /* not a valid boxed color */
+    { "GtkComboBox",            "row-span-column",      (void*) MATCH_ANY_VALUE },      /* GtkComboBoxEntry needs a tree model for this */
+    { "GtkComboBox",            "column-span-column",   (void*) MATCH_ANY_VALUE },      /* GtkComboBoxEntry needs a tree model for this */
+    { "GtkFileChooserButton",   "select-multiple",      (void*) MATCH_ANY_VALUE },      /* property disabled */
+    { "GtkFileChooserButton",   "action",               (void*) GTK_FILE_CHOOSER_ACTION_SAVE },
+    { "GtkFileChooserButton",   "action",               (void*) GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER },
+    { "GtkFileChooserWidget",   "select-multiple",      (void*) 0x1 },                  /* property conflicts */
+    { "GtkFileChooserDialog",   "select-multiple",      (void*) MATCH_ANY_VALUE },      /* property disabled */
+    { "GtkMenu",                "accel-path",           (void*) MATCH_ANY_VALUE },      /* has odd restrictions in the setter */
+    { "GtkMenuItem",            "accel-path",           (void*) MATCH_ANY_VALUE },      /* has odd restrictions in the setter */
+    { "GtkRecentChooserMenu",   "select-multiple",      (void*) MATCH_ANY_VALUE },      /* property disabled */
+    { "GtkTextView",            "overwrite",            (void*) MATCH_ANY_VALUE },      /* needs text buffer */
+    { "GtkToolbar",             "icon-size",            (void*) GTK_ICON_SIZE_INVALID },
+    { NULL, NULL, NULL }
+  };
+  /* properties suspected to be Gdk/Gtk+ bugs */
+  static const IgnoreProperty bug_properties[] = {
+    { "GtkComboBox",            "active",               (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL model bug */
+    { "GtkCTree",               "spacing",              (void*) MATCH_ANY_VALUE },      /* FIXME: triggers signedness bug */
+    { "GtkFileChooserButton",   "local-only",           (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL path assertion */
+    { "GtkFileChooserDialog",   "local-only",           (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL path assertion */
+    { "GtkFileChooserWidget",   "local-only",           (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL path assertion */
+    { "GtkMenu",                "tearoff-state",        (void*) MATCH_ANY_VALUE },      /* FIXME: triggers NULL widget cast */
+    { "GtkText",                "text-position",        (void*) MATCH_ANY_VALUE },      /* FIXME: segfaults, fix property minimum/maximum */
+    { NULL, NULL, NULL }
+  };
+  if (buglist)
+    return bug_properties;
+  else
+    return ignore_properties;
+}
+
+/* --- test functions --- */
+static void
+pspec_select_value (GParamSpec *pspec,
+                    GValue     *value,
+                    double      dvalue)
+{
+  /* generate a value suitable for pspec */
+  if (G_IS_PARAM_SPEC_CHAR (pspec))
+    ASSIGN_VALUE (g_value_set_char, value, GParamSpecChar*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_UCHAR (pspec))
+    ASSIGN_VALUE (g_value_set_uchar, value, GParamSpecUChar*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_INT (pspec))
+    ASSIGN_VALUE (g_value_set_int, value, GParamSpecInt*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_UINT (pspec))
+    ASSIGN_VALUE (g_value_set_uint, value, GParamSpecUInt*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_LONG (pspec))
+    ASSIGN_VALUE (g_value_set_long, value, GParamSpecLong*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_ULONG (pspec))
+    ASSIGN_VALUE (g_value_set_ulong, value, GParamSpecULong*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_INT64 (pspec))
+    ASSIGN_VALUE (g_value_set_int64, value, GParamSpecInt64*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_UINT64 (pspec))
+    ASSIGN_VALUE (g_value_set_uint64, value, GParamSpecUInt64*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_FLOAT (pspec))
+    ASSIGN_VALUE (g_value_set_float, value, GParamSpecFloat*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
+    ASSIGN_VALUE (g_value_set_double, value, GParamSpecDouble*, pspec, default_value, minimum, maximum, dvalue);
+  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
+    g_value_set_boolean (value, SELECT_VALUE (dvalue, ((GParamSpecBoolean*) pspec)->default_value, FALSE, TRUE));
+  else if (G_IS_PARAM_SPEC_UNICHAR (pspec))
+    g_value_set_uint (value, SELECT_VALUE (dvalue, ((GParamSpecUnichar*) pspec)->default_value, FALSE, TRUE));
+  else if (G_IS_PARAM_SPEC_GTYPE (pspec))
+    g_value_set_gtype (value, SELECT_VALUE ((int) dvalue, ((GParamSpecGType*) pspec)->is_a_type, 0, GTK_TYPE_WIDGET));
+  else if (G_IS_PARAM_SPEC_STRING (pspec))
+    {
+      GParamSpecString *sspec = (GParamSpecString*) pspec;
+      if (dvalue >= +2)
+        g_value_set_string (value, sspec->default_value);
+      if (dvalue > 0 && sspec->cset_first && sspec->cset_nth)
+        g_value_take_string (value, g_strdup_printf ("%c%c", sspec->cset_first[0], sspec->cset_nth[0]));
+      else /* if (sspec->ensure_non_null) */
+        g_value_set_string (value, "");
+    }
+  else if (G_IS_PARAM_SPEC_ENUM (pspec))
+    {
+      GParamSpecEnum *espec = (GParamSpecEnum*) pspec;
+      if (dvalue >= +2)
+        g_value_set_enum (value, espec->default_value);
+      if (dvalue >= 0 && dvalue <= 1)
+        g_value_set_enum (value, espec->enum_class->values[(int) ((espec->enum_class->n_values - 1) * dvalue)].value);
+      else if (dvalue <= -1)
+        g_value_set_enum (value, espec->enum_class->values[g_test_rand_int_range (0, espec->enum_class->n_values)].value);
+    }
+  else if (G_IS_PARAM_SPEC_FLAGS (pspec))
+    {
+      GParamSpecFlags *fspec = (GParamSpecFlags*) pspec;
+      if (dvalue >= +2)
+        g_value_set_flags (value, fspec->default_value);
+      if (dvalue >= 0 && dvalue <= 1)
+        g_value_set_flags (value, fspec->flags_class->values[(int) ((fspec->flags_class->n_values - 1) * dvalue)].value);
+      else if (dvalue <= -1)
+        g_value_set_flags (value, fspec->flags_class->values[g_test_rand_int_range (0, fspec->flags_class->n_values)].value);
+    }
+  /* unimplemented:
+   * G_IS_PARAM_SPEC_PARAM
+   * G_IS_PARAM_SPEC_BOXED
+   * G_IS_PARAM_SPEC_POINTER
+   * G_IS_PARAM_SPEC_VALUE_ARRAY
+   * G_IS_PARAM_SPEC_OBJECT
+   */
+}
+
+static gpointer
+value_as_pointer (GValue *value)
+{
+  if (g_value_fits_pointer (value))
+    return g_value_peek_pointer (value);
+  if (G_VALUE_HOLDS_BOOLEAN (value))
+    return GINT_TO_POINTER(g_value_get_boolean (value));
+  if (G_VALUE_HOLDS_CHAR (value))
+    return (void*) (gssize) g_value_get_char (value);
+  if (G_VALUE_HOLDS_UCHAR (value))
+    return (void*) (gsize) g_value_get_uchar (value);
+  if (G_VALUE_HOLDS_INT (value))
+    return GINT_TO_POINTER(g_value_get_int (value));
+  if (G_VALUE_HOLDS_UINT (value))
+    return GUINT_TO_POINTER(g_value_get_uint (value));
+  if (G_VALUE_HOLDS_LONG (value))
+    return (void*) g_value_get_long (value);
+  if (G_VALUE_HOLDS_ULONG (value))
+    return (void*) g_value_get_ulong (value);
+  if (G_VALUE_HOLDS_FLOAT (value))
+    return (void*) (gssize) g_value_get_float (value);
+  if (G_VALUE_HOLDS_DOUBLE (value))
+    return (void*) (gssize) g_value_get_double (value);
+  if (G_VALUE_HOLDS_ENUM (value))
+    return (void*) (gssize) g_value_get_enum (value);
+  if (G_VALUE_HOLDS_FLAGS (value))
+    return (void*) (gsize) g_value_get_flags (value);
+  return (void*) 0x1373babe;
+}
+
+static void
+object_test_property (GObject           *object,
+                      GParamSpec        *pspec,
+                      double             dvalue)
+{
+  /* test setting of a normal writable property */
+  if (pspec->flags & G_PARAM_WRITABLE &&
+      !(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
+    {
+      GValue value = G_VALUE_INIT;
+      guint i;
+      const IgnoreProperty *ignore_properties;
+      /* select value to set */
+      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      pspec_select_value (pspec, &value, dvalue);
+      /* ignore untestable properties */
+      ignore_properties = list_ignore_properties (FALSE);
+      for (i = 0; ignore_properties[i].name; i++)
+        if (g_strcmp0 ("", ignore_properties[i].name) ||
+            (g_type_is_a (G_OBJECT_TYPE (object), g_type_from_name (ignore_properties[i].type_name)) &&
+             strcmp (pspec->name, ignore_properties[i].name) == 0 &&
+             (MATCH_ANY_VALUE == ignore_properties[i].value ||
+              value_as_pointer (&value) == ignore_properties[i].value ||
+              (G_VALUE_HOLDS_STRING (&value) &&
+               strcmp (g_value_get_string (&value), ignore_properties[i].value) == 0))))
+          break;
+      /* ignore known property bugs if not testing thoroughly */
+      if (ignore_properties[i].name == NULL && !g_test_thorough ())
+        {
+          ignore_properties = list_ignore_properties (TRUE);
+          for (i = 0; ignore_properties[i].name; i++)
+            if (g_type_is_a (G_OBJECT_TYPE (object), g_type_from_name (ignore_properties[i].type_name)) &&
+                strcmp (pspec->name, ignore_properties[i].name) == 0 &&
+                (MATCH_ANY_VALUE == ignore_properties[i].value ||
+                 value_as_pointer (&value) == ignore_properties[i].value ||
+                 (G_VALUE_HOLDS_STRING (&value) &&
+                  strcmp (g_value_get_string (&value), ignore_properties[i].value) == 0)))
+              break;
+        }
+      /* assign unignored properties */
+      if (ignore_properties[i].name == NULL)
+        {
+          if (g_test_verbose ())
+            g_print ("PropertyTest: %s::%s := (%s value (%s): %p)\n",
+                     g_type_name (G_OBJECT_TYPE (object)), pspec->name,
+                     SELECT_NAME (dvalue), g_type_name (G_VALUE_TYPE (&value)),
+                     value_as_pointer (&value));
+          g_object_set_property (object, pspec->name, &value);
+        }
+      /* cleanups */
+      g_value_unset (&value);
+    }
+}
+
+static void
+widget_test_properties (GtkWidget   *widget,
+                        double       dvalue)
+{
+  /* try setting all possible properties, according to dvalue */
+  guint i, n_pspecs = 0;
+  GParamSpec **pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (widget), &n_pspecs);
+  for (i = 0; i < n_pspecs; i++)
+    {
+      GParamSpec *pspec = pspecs[i];
+      if (pspec->flags & G_PARAM_WRITABLE &&
+          !(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
+        object_test_property (G_OBJECT (widget), pspecs[i], dvalue);
+    }
+  g_free (pspecs);
+}
+
+static void
+widget_fixups (GtkWidget *widget)
+{
+  /* post-constructor for widgets that need additional settings to work correctly */
+  if (GTK_IS_COMBO_BOX (widget))
+    {
+      GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
+      g_object_set (widget, "model", store, NULL);
+      g_object_unref (store);
+      gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "test text");
+    }
+}
+
+static void
+widget_property_tests (gconstpointer test_data)
+{
+  GType wtype = (GType) test_data;
+  /* create widget */
+  GtkWidget *widget = gtk_widget_new (wtype, NULL);
+  g_object_ref_sink (widget);
+  widget_fixups (widget);
+  /* test property values */
+  widget_test_properties (widget,  +2); /* test default_value */
+  widget_test_properties (widget,   0); /* test minimum */
+  widget_test_properties (widget, 0.5); /* test medium */
+  widget_test_properties (widget,   1); /* test maximum */
+  widget_test_properties (widget,  -1); /* test random value */
+  /* cleanup */
+  gtk_widget_destroy (widget);
+  g_object_unref (widget);
+}
+
+/* --- main test program --- */
+int
+main (int   argc,
+      char *argv[])
+{
+  const GType *otypes;
+  guint i;
+  /* initialize test program */
+  gtk_test_init (&argc, &argv);
+  gtk_test_register_all_types ();
+  /* install a property test for each widget type */
+  otypes = gtk_test_list_all_types (NULL);
+  for (i = 0; otypes[i]; i++)
+    if (g_type_is_a (otypes[i], GTK_TYPE_WIDGET) &&
+        G_TYPE_IS_OBJECT (otypes[i]) &&
+        !G_TYPE_IS_ABSTRACT (otypes[i]))
+      {
+        gchar *testpath = g_strdup_printf ("/properties/%s", g_type_name (otypes[i]));
+        g_test_add_data_func (testpath, (void*) otypes[i], widget_property_tests);
+        g_free (testpath);
+      }
+  return g_test_run ();
+}
diff --git a/testsuite/gtk/objects-finalize.c b/testsuite/gtk/objects-finalize.c
new file mode 100644 (file)
index 0000000..0e1eae0
--- /dev/null
@@ -0,0 +1,114 @@
+/* objects-finalize.c
+ * Copyright (C) 2013 Openismus GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Tristan Van Berkom <tristanvb@openismus.com>
+ */
+#include <gtk/gtk.h>
+#include <string.h>
+
+#ifdef GDK_WINDOWING_X11
+# include <gdk/gdkx.h>
+#endif
+
+
+typedef GType (*GTypeGetFunc) (void);
+
+static gboolean finalized = FALSE;
+
+static gboolean
+main_loop_quit_cb (gpointer data)
+{
+  gtk_main_quit ();
+
+  g_assert (finalized);
+  return FALSE;
+}
+
+static void
+check_finalized (gpointer data,
+                GObject *where_the_object_was)
+{
+  gboolean *did_finalize = (gboolean *)data;
+
+  *did_finalize = TRUE;
+}
+
+static void
+test_finalize_object (gconstpointer data)
+{
+  GType test_type = GPOINTER_TO_SIZE (data);
+  GObject *object;
+
+  object = g_object_new (test_type, NULL);
+  g_assert (G_IS_OBJECT (object));
+
+  /* Make sure we have the only reference */
+  if (g_object_is_floating (object))
+    g_object_ref_sink (object);
+
+  /* Assert that the object finalizes properly */
+  g_object_weak_ref (object, check_finalized, &finalized);
+
+  /* Toplevels are owned by GTK+, just tell GTK+ to destroy it */
+  if (GTK_IS_WINDOW (object) || GTK_IS_INVISIBLE (object))
+    gtk_widget_destroy (GTK_WIDGET (object));
+  else
+    g_object_unref (object);
+
+  /* Even if the object did finalize, it may have left some dangerous stuff in the GMainContext */
+  g_timeout_add (50, main_loop_quit_cb, NULL);
+  gtk_main();
+}
+
+int
+main (int argc, char **argv)
+{
+  const GType *all_types;
+  guint n_types = 0, i;
+
+  /* initialize test program */
+  gtk_test_init (&argc, &argv);
+  gtk_test_register_all_types ();
+
+  all_types = gtk_test_list_all_types (&n_types);
+
+  for (i = 0; i < n_types; i++)
+    {
+      if (g_type_is_a (all_types[i], G_TYPE_OBJECT) &&
+         G_TYPE_IS_INSTANTIATABLE (all_types[i]) &&
+         !G_TYPE_IS_ABSTRACT (all_types[i]) &&
+#ifdef GDK_WINDOWING_X11
+         all_types[i] != GDK_TYPE_X11_WINDOW &&
+         all_types[i] != GDK_TYPE_X11_CURSOR &&
+         all_types[i] != GDK_TYPE_X11_SCREEN &&
+         all_types[i] != GDK_TYPE_X11_DISPLAY &&
+         all_types[i] != GDK_TYPE_X11_DEVICE_MANAGER_XI2 &&
+         all_types[i] != GDK_TYPE_X11_DISPLAY_MANAGER &&
+#endif
+         /* Not allowed to finalize a GdkPixbufLoader without calling gdk_pixbuf_loader_close() */
+         all_types[i] != GDK_TYPE_PIXBUF_LOADER &&
+         all_types[i] != gdk_pixbuf_simple_anim_iter_get_type())
+       {
+         gchar *test_path = g_strdup_printf ("/FinalizeObject/%s", g_type_name (all_types[i]));
+
+         g_test_add_data_func (test_path, GSIZE_TO_POINTER (all_types[i]), test_finalize_object);
+
+         g_free (test_path);
+       }
+    }
+
+  return g_test_run();
+}
diff --git a/testsuite/gtk/papersize.c b/testsuite/gtk/papersize.c
new file mode 100644 (file)
index 0000000..6af7acc
--- /dev/null
@@ -0,0 +1,126 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+static void
+test_parse (void)
+{
+  GtkPaperSize *p;
+
+  p = gtk_paper_size_new (GTK_PAPER_NAME_A4);
+  g_assert (p != NULL);
+  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
+  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
+  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_a4");
+  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "A4");
+  g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "A4");
+  g_assert (!gtk_paper_size_is_custom (p));
+  gtk_paper_size_free (p);
+
+  p = gtk_paper_size_new (GTK_PAPER_NAME_B5);
+  g_assert (p != NULL);
+  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 176);
+  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 250);
+  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_b5");
+  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "B5");
+  g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "ISOB5");
+  g_assert (!gtk_paper_size_is_custom (p));
+  gtk_paper_size_free (p);
+
+  p = gtk_paper_size_new (GTK_PAPER_NAME_EXECUTIVE);
+  g_assert (p != NULL);
+  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 184);
+  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 266);
+  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "na_executive");
+  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "Executive");
+  g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "Executive");
+  g_assert (!gtk_paper_size_is_custom (p));
+  gtk_paper_size_free (p);
+
+  p = gtk_paper_size_new ("iso_a4_210x297mm");
+  g_assert (p != NULL);
+  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
+  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
+  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "iso_a4");
+  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "A4");
+  g_assert_cmpstr (gtk_paper_size_get_ppd_name (p), ==, "A4");
+  g_assert (!gtk_paper_size_is_custom (p));
+  gtk_paper_size_free (p);
+
+  p = gtk_paper_size_new ("custom_w1_20x30in");
+  g_assert (p != NULL);
+  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_INCH), ==, 20);
+  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_INCH), ==, 30);
+  g_assert_cmpstr (gtk_paper_size_get_name (p), ==, "custom_w1");
+  g_assert_cmpstr (gtk_paper_size_get_display_name (p), ==, "custom_w1");
+  g_assert (gtk_paper_size_is_custom (p));
+  gtk_paper_size_free (p);
+}
+
+static void
+test_compare (void)
+{
+  GtkPaperSize *a1, *a2, *b, *c;
+
+  a1 = gtk_paper_size_new (GTK_PAPER_NAME_A4);
+  a2 = gtk_paper_size_new ("iso_a4_210x297mm");
+  b = gtk_paper_size_new (GTK_PAPER_NAME_B5);
+  c = gtk_paper_size_new ("custom_w1_20x30in");
+
+  g_assert (gtk_paper_size_is_equal (a1, a2));
+  g_assert (!gtk_paper_size_is_equal (a1, b));
+  g_assert (!gtk_paper_size_is_equal (a1, c));
+  g_assert (!gtk_paper_size_is_equal (b, c));
+
+  gtk_paper_size_free (a1);
+  gtk_paper_size_free (a2);
+  gtk_paper_size_free (b);
+  gtk_paper_size_free (c);
+}
+
+static void
+test_units (void)
+{
+  GtkPaperSize *p;
+
+  p = gtk_paper_size_new (GTK_PAPER_NAME_A4);
+
+  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_MM), ==, 210);
+  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_MM), ==, 297);
+
+  /* compare up to 2 decimals */
+  g_assert_cmpint (100 * gtk_paper_size_get_width (p, GTK_UNIT_INCH), ==, 100 * 8.26);
+  g_assert_cmpint (100 * gtk_paper_size_get_height (p, GTK_UNIT_INCH), ==, 100 * 11.69);
+
+  g_assert_cmpint (gtk_paper_size_get_width (p, GTK_UNIT_POINTS), ==, 595);
+  g_assert_cmpint (gtk_paper_size_get_height (p, GTK_UNIT_POINTS), ==, 841);
+
+  gtk_paper_size_free (p);
+}
+
+int
+main (int argc, char *argv[])
+{
+  gtk_test_init (&argc, &argv);
+
+  g_test_add_func ("/paper-size/parse", test_parse);
+  g_test_add_func ("/paper-size/compare", test_compare);
+  g_test_add_func ("/paper-size/units", test_units);
+
+  return g_test_run();
+}
diff --git a/testsuite/gtk/rbtree.c b/testsuite/gtk/rbtree.c
new file mode 100644 (file)
index 0000000..d73d862
--- /dev/null
@@ -0,0 +1,525 @@
+/* GtkRBTree tests.
+ *
+ * Copyright (C) 2011, Red Hat, Inc.
+ * Authors: Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <locale.h>
+
+#include "../../gtk/gtkrbtree.h"
+
+/* _gtk_rbtree_test */
+
+static guint
+get_total_count (GtkRBNode *node)
+{
+  guint child_total = 0;
+
+  child_total += (guint) node->left->total_count;
+  child_total += (guint) node->right->total_count;
+
+  if (node->children)
+    child_total += (guint) node->children->root->total_count;
+
+  return child_total + 1;
+}
+
+static guint
+count_total (GtkRBTree *tree,
+             GtkRBNode *node)
+{
+  guint res;
+  
+  if (_gtk_rbtree_is_nil (node))
+    return 0;
+  
+  res =
+    count_total (tree, node->left) +
+    count_total (tree, node->right) +
+    (guint)1 +
+    (node->children ? count_total (node->children, node->children->root) : 0);
+
+  if (res != node->total_count)
+    g_print ("total count incorrect for node\n");
+
+  if (get_total_count (node) != node->total_count)
+    g_error ("Node has incorrect total count %u, should be %u", node->total_count, get_total_count (node));
+  
+  return res;
+}
+
+static gint
+_count_nodes (GtkRBTree *tree,
+              GtkRBNode *node)
+{
+  gint res;
+  if (_gtk_rbtree_is_nil (node))
+    return 0;
+
+  g_assert (node->left);
+  g_assert (node->right);
+
+  res = (_count_nodes (tree, node->left) +
+         _count_nodes (tree, node->right) + 1);
+
+  if (res != node->count)
+    g_print ("Tree failed\n");
+  return res;
+}
+
+static void
+_gtk_rbtree_test_height (GtkRBTree *tree,
+                         GtkRBNode *node)
+{
+  gint computed_offset = 0;
+
+  /* This whole test is sort of a useless truism. */
+  
+  if (!_gtk_rbtree_is_nil (node->left))
+    computed_offset += node->left->offset;
+
+  if (!_gtk_rbtree_is_nil (node->right))
+    computed_offset += node->right->offset;
+
+  if (node->children && !_gtk_rbtree_is_nil (node->children->root))
+    computed_offset += node->children->root->offset;
+
+  if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset)
+    g_error ("node has broken offset\n");
+
+  if (!_gtk_rbtree_is_nil (node->left))
+    _gtk_rbtree_test_height (tree, node->left);
+
+  if (!_gtk_rbtree_is_nil (node->right))
+    _gtk_rbtree_test_height (tree, node->right);
+
+  if (node->children && !_gtk_rbtree_is_nil (node->children->root))
+    _gtk_rbtree_test_height (node->children, node->children->root);
+}
+
+static void
+_gtk_rbtree_test_dirty (GtkRBTree *tree,
+                       GtkRBNode *node,
+                        gint      expected_dirtyness)
+{
+
+  if (expected_dirtyness)
+    {
+      g_assert (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) ||
+               GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
+               GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID) ||
+               GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID) ||
+               (node->children && GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID)));
+    }
+  else
+    {
+      g_assert (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID) &&
+               ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID));
+      if (!_gtk_rbtree_is_nil (node->left))
+       g_assert (! GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
+      if (!_gtk_rbtree_is_nil (node->right))
+       g_assert (! GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
+      if (node->children != NULL)
+       g_assert (! GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
+    }
+
+  if (!_gtk_rbtree_is_nil (node->left))
+    _gtk_rbtree_test_dirty (tree, node->left, GTK_RBNODE_FLAG_SET (node->left, GTK_RBNODE_DESCENDANTS_INVALID));
+  if (!_gtk_rbtree_is_nil (node->right))
+    _gtk_rbtree_test_dirty (tree, node->right, GTK_RBNODE_FLAG_SET (node->right, GTK_RBNODE_DESCENDANTS_INVALID));
+  if (node->children != NULL && !_gtk_rbtree_is_nil (node->children->root))
+    _gtk_rbtree_test_dirty (node->children, node->children->root, GTK_RBNODE_FLAG_SET (node->children->root, GTK_RBNODE_DESCENDANTS_INVALID));
+}
+
+static void _gtk_rbtree_test_structure (GtkRBTree *tree);
+
+static guint
+_gtk_rbtree_test_structure_helper (GtkRBTree *tree,
+                                  GtkRBNode *node)
+{
+  guint left_blacks, right_blacks;
+
+  g_assert (!_gtk_rbtree_is_nil (node));
+
+  g_assert (node->left != NULL);
+  g_assert (node->right != NULL);
+  g_assert (node->parent != NULL);
+
+  if (!_gtk_rbtree_is_nil (node->left))
+    {
+      g_assert (node->left->parent == node);
+      left_blacks = _gtk_rbtree_test_structure_helper (tree, node->left);
+    }
+  else
+    left_blacks = 0;
+
+  if (!_gtk_rbtree_is_nil (node->right))
+    {
+      g_assert (node->right->parent == node);
+      right_blacks = _gtk_rbtree_test_structure_helper (tree, node->right);
+    }
+  else
+    right_blacks = 0;
+
+  if (node->children != NULL)
+    {
+      g_assert (node->children->parent_tree == tree);
+      g_assert (node->children->parent_node == node);
+
+      _gtk_rbtree_test_structure (node->children);
+    }
+
+  g_assert (left_blacks == right_blacks);
+
+  return left_blacks + (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK ? 1 : 0);
+}
+
+static void
+_gtk_rbtree_test_structure (GtkRBTree *tree)
+{
+  g_assert (tree->root);
+  if (_gtk_rbtree_is_nil (tree->root))
+    return;
+
+  g_assert (_gtk_rbtree_is_nil (tree->root->parent));
+  _gtk_rbtree_test_structure_helper (tree, tree->root);
+}
+
+static void
+_gtk_rbtree_test (GtkRBTree *tree)
+{
+  GtkRBTree *tmp_tree;
+
+  if (tree == NULL)
+    return;
+
+  /* Test the entire tree */
+  tmp_tree = tree;
+  while (tmp_tree->parent_tree)
+    tmp_tree = tmp_tree->parent_tree;
+  
+  if (_gtk_rbtree_is_nil (tmp_tree->root))
+    return;
+
+  _gtk_rbtree_test_structure (tmp_tree);
+
+  g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) +
+            _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count);
+      
+  _gtk_rbtree_test_height (tmp_tree, tmp_tree->root);
+  _gtk_rbtree_test_dirty (tmp_tree, tmp_tree->root, GTK_RBNODE_FLAG_SET (tmp_tree->root, GTK_RBNODE_DESCENDANTS_INVALID));
+  g_assert (count_total (tmp_tree, tmp_tree->root) == tmp_tree->root->total_count);
+}
+
+/* gtk_rbtree_print() - unused, for debugging only */
+
+static void
+gtk_rbtree_print_node (GtkRBTree *tree,
+                       GtkRBNode *node,
+                       gint       depth)
+{
+  gint i;
+  for (i = 0; i < depth; i++)
+    g_print ("\t");
+
+  g_print ("(%p - %s) (Offset %d) (Parity %d) (Validity %d%d%d)\n",
+          node,
+          (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK)?"BLACK":" RED ",
+          node->offset,
+          node->total_count,
+          (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_DESCENDANTS_INVALID))?1:0,
+          (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID))?1:0,
+          (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))?1:0);
+  if (node->children != NULL)
+    {
+      g_print ("Looking at child.\n");
+      gtk_rbtree_print_node (node->children, node->children->root, depth + 1);
+      g_print ("Done looking at child.\n");
+    }
+  if (!_gtk_rbtree_is_nil (node->left))
+    {
+      gtk_rbtree_print_node (tree, node->left, depth+1);
+    }
+  if (!_gtk_rbtree_is_nil (node->right))
+    {
+      gtk_rbtree_print_node (tree, node->right, depth+1);
+    }
+}
+
+/* not static so the debugger finds it. */
+void gtk_rbtree_print (GtkRBTree *tree);
+
+void
+gtk_rbtree_print (GtkRBTree *tree)
+{
+  g_return_if_fail (tree != NULL);
+
+  if (_gtk_rbtree_is_nil (tree->root))
+    g_print ("Empty tree...\n");
+  else
+    gtk_rbtree_print_node (tree, tree->root, 0);
+}
+
+/* actual tests */
+
+static guint
+append_elements (GtkRBTree *tree,
+                 guint      depth,
+                 guint      elements_per_depth,
+                 gboolean   check,
+                 guint      height)
+{
+  GtkRBNode *node;
+  guint i;
+
+  g_assert (depth > 0);
+
+  node = NULL;
+  depth--;
+
+  for (i = 0; i < elements_per_depth; i++)
+    {
+      node = _gtk_rbtree_insert_after (tree, node, ++height, TRUE);
+      if (depth)
+        {
+          node->children = _gtk_rbtree_new ();
+          node->children->parent_tree = tree;
+          node->children->parent_node = node;
+          height = append_elements (node->children, depth, elements_per_depth, check, height);
+        }
+      if (check)
+        _gtk_rbtree_test (tree);
+    }
+
+  return height;
+}
+
+static GtkRBTree *
+create_rbtree (guint depth,
+               guint elements_per_depth,
+               gboolean check)
+{
+  GtkRBTree *tree;
+
+  tree = _gtk_rbtree_new ();
+
+  append_elements (tree, depth, elements_per_depth, check, 0);
+
+  _gtk_rbtree_test (tree);
+
+  return tree;
+}
+
+static void
+test_create (void)
+{
+  GtkRBTree *tree;
+
+  tree = create_rbtree (5, 5, TRUE);
+
+  _gtk_rbtree_free (tree);
+}
+
+static void
+test_insert_after (void)
+{
+  guint i;
+  GtkRBTree *tree;
+  GtkRBNode *node;
+
+  tree = _gtk_rbtree_new ();
+  node = NULL;
+
+  for (i = 1; i <= 100; i++)
+    {
+      node = _gtk_rbtree_insert_after (tree, node, i, TRUE);
+      _gtk_rbtree_test (tree);
+      g_assert (tree->root->count == i);
+      g_assert (tree->root->total_count == i);
+      g_assert (tree->root->offset == i * (i + 1) / 2);
+    }
+
+  _gtk_rbtree_free (tree);
+}
+
+static void
+test_insert_before (void)
+{
+  guint i;
+  GtkRBTree *tree;
+  GtkRBNode *node;
+
+  tree = _gtk_rbtree_new ();
+  node = NULL;
+
+  for (i = 1; i <= 100; i++)
+    {
+      node = _gtk_rbtree_insert_before (tree, node, i, TRUE);
+      _gtk_rbtree_test (tree);
+      g_assert (tree->root->count == i);
+      g_assert (tree->root->total_count == i);
+      g_assert (tree->root->offset == i * (i + 1) / 2);
+    }
+
+  _gtk_rbtree_free (tree);
+}
+
+static void
+test_remove_node (void)
+{
+  GtkRBTree *tree;
+
+  tree = create_rbtree (3, 16, g_test_thorough ());
+
+  while (tree->root->count > 1)
+    {
+      GtkRBTree *find_tree;
+      GtkRBNode *find_node;
+      guint i;
+      
+      i = g_test_rand_int_range (0, tree->root->total_count);
+      if (!_gtk_rbtree_find_index (tree, i, &find_tree, &find_node))
+        {
+          /* We search an available index, so we mustn't fail. */
+          g_assert_not_reached ();
+        }
+      
+      _gtk_rbtree_test (find_tree);
+
+      if (find_tree->root->count == 1)
+        {
+          _gtk_rbtree_remove (find_tree);
+        }
+      else
+        _gtk_rbtree_remove_node (find_tree, find_node);
+      _gtk_rbtree_test (tree);
+    }
+
+  _gtk_rbtree_free (tree);
+}
+
+static void
+test_remove_root (void)
+{
+  GtkRBTree *tree;
+  GtkRBNode *node;
+
+  tree = _gtk_rbtree_new ();
+  
+  node = _gtk_rbtree_insert_after (tree, NULL, 1, TRUE);
+  _gtk_rbtree_insert_after (tree, node, 2, TRUE);
+  _gtk_rbtree_insert_before (tree, node, 3, TRUE);
+
+  _gtk_rbtree_remove_node (tree, node);
+
+  _gtk_rbtree_free (tree);
+}
+
+static gint *
+fisher_yates_shuffle (guint n_items)
+{
+  gint *list;
+  guint i, j;
+
+  list = g_new (gint, n_items);
+
+  for (i = 0; i < n_items; i++)
+    {
+      j = g_random_int_range (0, i + 1);
+      list[i] = list[j];
+      list[j] = i;
+    }
+
+  return list;
+}
+
+static GtkRBTree *
+create_unsorted_tree (gint  *order,
+                      guint  n)
+{
+  GtkRBTree *tree;
+  GtkRBNode *node;
+  guint i;
+
+  tree = _gtk_rbtree_new ();
+  node = NULL;
+
+  for (i = 0; i < n; i++)
+    {
+      node = _gtk_rbtree_insert_after (tree, node, 0, TRUE);
+    }
+
+  for (i = 0; i < n; i++)
+    {
+      node = _gtk_rbtree_find_count (tree, order[i] + 1);
+      _gtk_rbtree_node_set_height (tree, node, i);
+    }
+
+  _gtk_rbtree_test (tree);
+
+  return tree;
+}
+
+static void
+test_reorder (void)
+{
+  guint n = g_test_perf () ? 1000000 : 100;
+  GtkRBTree *tree;
+  GtkRBNode *node;
+  gint *reorder;
+  guint i;
+  double elapsed;
+
+  reorder = fisher_yates_shuffle (n);
+  tree = create_unsorted_tree (reorder, n);
+
+  g_test_timer_start ();
+
+  _gtk_rbtree_reorder (tree, reorder, n);
+
+  elapsed = g_test_timer_elapsed ();
+  if (g_test_perf ())
+    g_test_minimized_result (elapsed, "reordering rbtree with %u items: %gsec", n, elapsed);
+
+  _gtk_rbtree_test (tree);
+
+  for (node = _gtk_rbtree_first (tree), i = 0;
+       node != NULL;
+       node = _gtk_rbtree_next (tree, node), i++)
+    {
+      g_assert (GTK_RBNODE_GET_HEIGHT (node) == i);
+    }
+  g_assert (i == n);
+
+  _gtk_rbtree_free (tree);
+}
+
+int
+main (int argc, char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+  setlocale (LC_ALL, "C");
+  g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
+
+  g_test_add_func ("/rbtree/create", test_create);
+  g_test_add_func ("/rbtree/insert_after", test_insert_after);
+  g_test_add_func ("/rbtree/insert_before", test_insert_before);
+  g_test_add_func ("/rbtree/remove_node", test_remove_node);
+  g_test_add_func ("/rbtree/remove_root", test_remove_root);
+  g_test_add_func ("/rbtree/reorder", test_reorder);
+
+  return g_test_run ();
+}
diff --git a/testsuite/gtk/recentmanager.c b/testsuite/gtk/recentmanager.c
new file mode 100644 (file)
index 0000000..84b7c67
--- /dev/null
@@ -0,0 +1,309 @@
+/* GTK - The GIMP Toolkit
+ * gtkrecentmanager.c: a manager for the recently used resources
+ *
+ * Copyright (C) 2006 Emmanuele Bassi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+
+const gchar *uri = "file:///tmp/testrecentchooser.txt";
+const gchar *uri2 = "file:///tmp/testrecentchooser2.txt";
+
+static void
+recent_manager_get_default (void)
+{
+  GtkRecentManager *manager;
+  GtkRecentManager *manager2;
+
+  manager = gtk_recent_manager_get_default ();
+  g_assert (manager != NULL);
+
+  manager2 = gtk_recent_manager_get_default ();
+  g_assert (manager == manager2);
+}
+
+static void
+recent_manager_add (void)
+{
+  GtkRecentManager *manager;
+  GtkRecentData *recent_data;
+  gboolean res;
+
+  manager = gtk_recent_manager_get_default ();
+
+  recent_data = g_slice_new0 (GtkRecentData);
+
+  /* mime type is mandatory */
+  recent_data->mime_type = NULL;
+  recent_data->app_name = "testrecentchooser";
+  recent_data->app_exec = "testrecentchooser %u";
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+    {
+      res = gtk_recent_manager_add_full (manager,
+                                         uri,
+                                         recent_data);
+    }
+  g_test_trap_assert_failed ();
+
+  /* app name is mandatory */
+  recent_data->mime_type = "text/plain";
+  recent_data->app_name = NULL;
+  recent_data->app_exec = "testrecentchooser %u";
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+    {
+      res = gtk_recent_manager_add_full (manager,
+                                         uri,
+                                         recent_data);
+    }
+  g_test_trap_assert_failed ();
+
+  /* app exec is mandatory */
+  recent_data->mime_type = "text/plain";
+  recent_data->app_name = "testrecentchooser";
+  recent_data->app_exec = NULL;
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
+    {
+      res = gtk_recent_manager_add_full (manager,
+                                         uri,
+                                         recent_data);
+    }
+  g_test_trap_assert_failed ();
+
+  recent_data->mime_type = "text/plain";
+  recent_data->app_name = "testrecentchooser";
+  recent_data->app_exec = "testrecentchooser %u";
+  res = gtk_recent_manager_add_full (manager,
+                                     uri,
+                                     recent_data);
+  g_assert (res == TRUE);
+
+  g_slice_free (GtkRecentData, recent_data);
+}
+
+typedef struct {
+  GMainLoop *main_loop;
+  gint counter;
+} AddManyClosure;
+
+static void
+check_bulk (GtkRecentManager *manager,
+            gpointer          data)
+{
+  AddManyClosure *closure = data;
+
+  if (g_test_verbose ())
+    g_print (G_STRLOC ": counter = %d\n", closure->counter);
+
+  g_assert_cmpint (closure->counter, ==, 100);
+
+  if (g_main_loop_is_running (closure->main_loop))
+    g_main_loop_quit (closure->main_loop);
+}
+
+static void
+recent_manager_add_many (void)
+{
+  GtkRecentManager *manager = g_object_new (GTK_TYPE_RECENT_MANAGER,
+                                            "filename", "recently-used.xbel",
+                                            NULL);
+  AddManyClosure *closure = g_new (AddManyClosure, 1);
+  GtkRecentData *data = g_slice_new0 (GtkRecentData);
+  gint i;
+
+  closure->main_loop = g_main_loop_new (NULL, FALSE);
+  closure->counter = 0;
+
+  g_signal_connect (manager, "changed", G_CALLBACK (check_bulk), closure);
+
+  for (i = 0; i < 100; i++)
+    {
+      gchar *new_uri;
+
+      data->mime_type = "text/plain";
+      data->app_name = "testrecentchooser";
+      data->app_exec = "testrecentchooser %u";
+
+      if (g_test_verbose ())
+        g_print (G_STRLOC ": adding item %d\n", i);
+
+      new_uri = g_strdup_printf ("file:///doesnotexist-%d.txt", i);
+      gtk_recent_manager_add_full (manager, new_uri, data);
+      g_free (new_uri);
+
+      closure->counter += 1;
+    }
+
+  g_main_loop_run (closure->main_loop);
+
+  g_main_loop_unref (closure->main_loop);
+  g_slice_free (GtkRecentData, data);
+  g_free (closure);
+  g_object_unref (manager);
+
+  g_assert_cmpint (g_unlink ("recently-used.xbel"), ==, 0);
+}
+
+static void
+recent_manager_has_item (void)
+{
+  GtkRecentManager *manager;
+  gboolean res;
+
+  manager = gtk_recent_manager_get_default ();
+
+  res = gtk_recent_manager_has_item (manager, "file:///tmp/testrecentdoesnotexist.txt");
+  g_assert (res == FALSE);
+
+  res = gtk_recent_manager_has_item (manager, uri);
+  g_assert (res == TRUE);
+}
+
+static void
+recent_manager_move_item (void)
+{
+  GtkRecentManager *manager;
+  gboolean res;
+  GError *error;
+
+  manager = gtk_recent_manager_get_default ();
+
+  error = NULL;
+  res = gtk_recent_manager_move_item (manager,
+                                      "file:///tmp/testrecentdoesnotexist.txt",
+                                      uri2,
+                                      &error);
+  g_assert (res == FALSE);
+  g_assert (error != NULL);
+  g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
+  g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
+  g_error_free (error);
+
+  error = NULL;
+  res = gtk_recent_manager_move_item (manager, uri, uri2, &error);
+  g_assert (res == TRUE);
+  g_assert (error == NULL);
+
+  res = gtk_recent_manager_has_item (manager, uri);
+  g_assert (res == FALSE);
+
+  res = gtk_recent_manager_has_item (manager, uri2);
+  g_assert (res == TRUE);
+}
+
+static void
+recent_manager_lookup_item (void)
+{
+  GtkRecentManager *manager;
+  GtkRecentInfo *info;
+  GError *error;
+
+  manager = gtk_recent_manager_get_default ();
+
+  error = NULL;
+  info = gtk_recent_manager_lookup_item (manager,
+                                         "file:///tmp/testrecentdoesnotexist.txt",
+                                         &error);
+  g_assert (info == NULL);
+  g_assert (error != NULL);
+  g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
+  g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
+  g_error_free (error);
+
+  error = NULL;
+  info = gtk_recent_manager_lookup_item (manager, uri2, &error);
+  g_assert (info != NULL);
+  g_assert (error == NULL);
+
+  g_assert (gtk_recent_info_has_application (info, "testrecentchooser"));
+
+  gtk_recent_info_unref (info);
+}
+
+static void
+recent_manager_remove_item (void)
+{
+  GtkRecentManager *manager;
+  gboolean res;
+  GError *error;
+
+  manager = gtk_recent_manager_get_default ();
+
+  error = NULL;
+  res = gtk_recent_manager_remove_item (manager,
+                                        "file:///tmp/testrecentdoesnotexist.txt",
+                                        &error);
+  g_assert (res == FALSE);
+  g_assert (error != NULL);
+  g_assert (error->domain == GTK_RECENT_MANAGER_ERROR);
+  g_assert (error->code == GTK_RECENT_MANAGER_ERROR_NOT_FOUND);
+  g_error_free (error);
+
+  /* remove an item that's actually there */
+  error = NULL;
+  res = gtk_recent_manager_remove_item (manager, uri2, &error);
+  g_assert (res == TRUE);
+  g_assert (error == NULL);
+
+  res = gtk_recent_manager_has_item (manager, uri2);
+  g_assert (res == FALSE);
+}
+
+static void
+recent_manager_purge (void)
+{
+  GtkRecentManager *manager;
+  GtkRecentData *recent_data;
+  gint n;
+  GError *error;
+
+  manager = gtk_recent_manager_get_default ();
+
+  /* purge, add 1, purge again and check that 1 item has been purged */
+  error = NULL;
+  n = gtk_recent_manager_purge_items (manager, &error);
+  g_assert (error == NULL);
+
+  recent_data = g_slice_new0 (GtkRecentData);
+  recent_data->mime_type = "text/plain";
+  recent_data->app_name = "testrecentchooser";
+  recent_data->app_exec = "testrecentchooser %u";
+  gtk_recent_manager_add_full (manager, uri, recent_data);
+  g_slice_free (GtkRecentData, recent_data);
+
+  error = NULL;
+  n = gtk_recent_manager_purge_items (manager, &error);
+  g_assert (error == NULL);
+  g_assert (n == 1);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  gtk_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/recent-manager/get-default", recent_manager_get_default);
+  g_test_add_func ("/recent-manager/add", recent_manager_add);
+  g_test_add_func ("/recent-manager/add-many", recent_manager_add_many);
+  g_test_add_func ("/recent-manager/has-item", recent_manager_has_item);
+  g_test_add_func ("/recent-manager/move-item", recent_manager_move_item);
+  g_test_add_func ("/recent-manager/lookup-item", recent_manager_lookup_item);
+  g_test_add_func ("/recent-manager/remove-item", recent_manager_remove_item);
+  g_test_add_func ("/recent-manager/purge", recent_manager_purge);
+
+  return g_test_run ();
+}
diff --git a/testsuite/gtk/regression-tests.c b/testsuite/gtk/regression-tests.c
new file mode 100644 (file)
index 0000000..e44eaa6
--- /dev/null
@@ -0,0 +1,68 @@
+/* Regression tests
+ *
+ * Copyright (C) 2011, Red Hat, Inc.
+ * Authors: Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+static void
+test_9d6da33ff5c5e41e3521e1afd63d2d67bc915753 (void)
+{
+  GtkWidget *window, *label;
+
+  window = gtk_window_new (GTK_WINDOW_POPUP);
+  label = gtk_label_new ("I am sensitive.");
+  gtk_container_add (GTK_CONTAINER (window), label);
+
+  gtk_widget_set_sensitive (label, FALSE);
+  gtk_widget_set_sensitive (window, FALSE);
+  gtk_widget_set_sensitive (label, TRUE);
+  gtk_widget_set_sensitive (window, TRUE);
+
+  g_assert (gtk_widget_get_sensitive (label));
+
+  gtk_widget_destroy (window);
+}
+
+static void
+test_94f00eb04dd1433cf1cc9a3341f485124e38abd1 (void)
+{
+  GtkWidget *window, *label;
+
+  window = gtk_window_new (GTK_WINDOW_POPUP);
+  label = gtk_label_new ("I am insensitive.");
+  gtk_container_add (GTK_CONTAINER (window), label);
+
+  gtk_widget_set_sensitive (window, FALSE);
+  gtk_widget_set_sensitive (label, FALSE);
+  gtk_widget_set_sensitive (label, TRUE);
+
+  g_assert (!gtk_widget_is_sensitive (label));
+
+  gtk_widget_destroy (window);
+}
+
+int
+main (int argc, char *argv[])
+{
+  gtk_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/regression/94f00eb04dd1433cf1cc9a3341f485124e38abd1", test_94f00eb04dd1433cf1cc9a3341f485124e38abd1);
+  g_test_add_func ("/regression/9d6da33ff5c5e41e3521e1afd63d2d67bc915753", test_9d6da33ff5c5e41e3521e1afd63d2d67bc915753);
+
+  return g_test_run ();
+}
diff --git a/testsuite/gtk/sortmodel.c b/testsuite/gtk/sortmodel.c
new file mode 100644 (file)
index 0000000..a24f8a3
--- /dev/null
@@ -0,0 +1,1243 @@
+/* Extensive GtkTreeModelSort tests.
+ * Copyright (C) 2009,2011  Kristian Rietveld  <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+#include "treemodel.h"
+#include "gtktreemodelrefcount.h"
+
+
+static void
+ref_count_single_level (void)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+
+  assert_root_level_unreferenced (ref_model);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (sort_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_two_levels (void)
+{
+  GtkTreeIter parent1, parent2, iter;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_node_ref_count (ref_model, &iter, 0);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter, 1);
+
+  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter, 0);
+
+  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_node_ref_count (ref_model, &iter, 0);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (sort_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_three_levels (void)
+{
+  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
+  GtkTreeIter iter_parent1, iter_parent2;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   *   + parent1
+   *     + iter_parent1
+   *   + parent2
+   *     + iter_parent2
+   *     + iter_parent2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_unreferenced (ref_model, &parent2);
+
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 0);
+
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_path_append_index (path, 1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_path_up (path);
+  gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (sort_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_delete_row (void)
+{
+  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
+  GtkTreeIter iter_parent1, iter_parent2;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkTreePath *path;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   *   + parent1
+   *     + iter_parent1
+   *   + parent2
+   *     + iter_parent2
+   *     + iter_parent2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  assert_root_level_referenced (ref_model, 1);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 0);
+  assert_level_unreferenced (ref_model, &parent1);
+  assert_level_unreferenced (ref_model, &parent2);
+
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 1);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &iter_parent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 2);
+  assert_level_referenced (ref_model, 1, &parent1);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_level_referenced (ref_model, 1, &parent2);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_level_referenced (ref_model, 1, &parent2);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+
+  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+
+  gtk_widget_destroy (tree_view);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (sort_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_cleanup (void)
+{
+  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
+  GtkTreeIter iter_parent1, iter_parent2;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   *   + parent1
+   *     + iter_parent1
+   *   + parent2
+   *     + iter_parent2
+   *     + iter_parent2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  gtk_widget_destroy (tree_view);
+
+  assert_node_ref_count (ref_model, &grandparent1, 0);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &parent1, 1);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (sort_model);
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_row_ref (void)
+{
+  GtkTreeIter grandparent1, grandparent2, parent1, parent2;
+  GtkTreeIter iter_parent1, iter_parent2;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+  GtkTreePath *path;
+  GtkTreeRowReference *row_ref;
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  /* + grandparent1
+   * + grandparent2
+   *   + parent1
+   *     + iter_parent1
+   *   + parent2
+   *     + iter_parent2
+   *     + iter_parent2
+   */
+
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+  gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
+  row_ref = gtk_tree_row_reference_new (sort_model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  /* Referenced because the node is visible, its child level is built
+   * and referenced by the row ref.
+   */
+  assert_node_ref_count (ref_model, &grandparent2, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  /* Referenced by the row ref and because its child level is built. */
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 2);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &parent2, 1);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 0);
+
+  path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
+  row_ref = gtk_tree_row_reference_new (sort_model, path);
+  gtk_tree_path_free (path);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  /* Referenced because the node is visible, its child level is built
+   * and referenced by the row ref.
+   */
+  assert_node_ref_count (ref_model, &grandparent2, 3);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  /* Referenced by the row ref and because its child level is built. */
+  assert_node_ref_count (ref_model, &parent2, 2);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent2, 1);
+
+  gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+
+  gtk_tree_row_reference_free (row_ref);
+
+  assert_node_ref_count (ref_model, &grandparent1, 1);
+  assert_node_ref_count (ref_model, &grandparent2, 1);
+  assert_node_ref_count (ref_model, &parent1, 0);
+  assert_node_ref_count (ref_model, &iter_parent1, 0);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (sort_model);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_reorder_single (void)
+{
+  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
+  GtkTreeIter siter1, siter2, siter3, siter4, siter5;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_INT };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
+                                     0, 30, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
+                                     0, 40, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
+                                     0, 10, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
+                                     0, 20, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
+                                     0, 60, -1);
+
+  assert_root_level_unreferenced (ref_model);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter5);
+
+  assert_node_ref_count (ref_model, &iter1, 3);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &iter3, 4);
+  assert_node_ref_count (ref_model, &iter4, 1);
+  assert_node_ref_count (ref_model, &iter5, 2);
+
+  /* Sort */
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_ASCENDING);
+
+  assert_node_ref_count (ref_model, &iter1, 3);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &iter3, 4);
+  assert_node_ref_count (ref_model, &iter4, 1);
+  assert_node_ref_count (ref_model, &iter5, 2);
+
+  /* Re-translate the iters after sorting */
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter5);
+
+  assert_entire_model_referenced (ref_model, 1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (sort_model);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+ref_count_reorder_two (void)
+{
+  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
+  GtkTreeIter citer1, citer2, citer3, citer4, citer5;
+  GtkTreeIter siter1, siter2, siter3, siter4, siter5;
+  GtkTreeIter sciter1, sciter2, sciter3, sciter4, sciter5;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+  GType column_types[] = { G_TYPE_INT };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
+                                     0, 30, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
+                                     0, 40, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
+                                     0, 10, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
+                                     0, 20, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
+                                     0, 60, -1);
+
+  /* Child level */
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer1, &iter1, 0,
+                                     0, 30, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer2, &iter1, 1,
+                                     0, 40, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer3, &iter1, 2,
+                                     0, 10, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer4, &iter1, 3,
+                                     0, 20, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer5, &iter1, 4,
+                                     0, 60, -1);
+
+  assert_root_level_unreferenced (ref_model);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  assert_node_ref_count (ref_model, &iter1, 2);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &iter3, 1);
+  assert_node_ref_count (ref_model, &iter4, 1);
+  assert_node_ref_count (ref_model, &iter5, 1);
+
+  assert_level_referenced (ref_model, 1, &iter1);
+
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
+
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter1, &citer1);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter2, &citer2);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter3, &citer3);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter4, &citer4);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter5, &citer5);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter5);
+
+  assert_node_ref_count (ref_model, &iter1, 4);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &iter3, 4);
+  assert_node_ref_count (ref_model, &iter4, 1);
+  assert_node_ref_count (ref_model, &iter5, 2);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter3);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter3);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
+
+  gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter1);
+
+  assert_node_ref_count (ref_model, &citer1, 2);
+  assert_node_ref_count (ref_model, &citer2, 1);
+  assert_node_ref_count (ref_model, &citer3, 3);
+  assert_node_ref_count (ref_model, &citer4, 1);
+  assert_node_ref_count (ref_model, &citer5, 4);
+
+  /* Sort */
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_ASCENDING);
+
+  assert_node_ref_count (ref_model, &iter1, 4);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &iter3, 4);
+  assert_node_ref_count (ref_model, &iter4, 1);
+  assert_node_ref_count (ref_model, &iter5, 2);
+
+  assert_node_ref_count (ref_model, &citer1, 2);
+  assert_node_ref_count (ref_model, &citer2, 1);
+  assert_node_ref_count (ref_model, &citer3, 3);
+  assert_node_ref_count (ref_model, &citer4, 1);
+  assert_node_ref_count (ref_model, &citer5, 4);
+
+  /* Re-translate the iters after sorting */
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
+
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter1, &citer1);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter2, &citer2);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter3, &citer3);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter4, &citer4);
+  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter5, &citer5);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter5);
+
+  assert_node_ref_count (ref_model, &iter1, 2);
+  assert_node_ref_count (ref_model, &iter2, 1);
+  assert_node_ref_count (ref_model, &iter3, 1);
+  assert_node_ref_count (ref_model, &iter4, 1);
+  assert_node_ref_count (ref_model, &iter5, 1);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter3);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter3);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
+
+  gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter1);
+
+  assert_level_referenced (ref_model, 1, &iter1);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (sort_model);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+check_sort_order (GtkTreeModel *sort_model,
+                  GtkSortType   sort_order,
+                  const char   *parent_path)
+{
+  int prev_value;
+  GtkTreeIter siter;
+
+  if (!parent_path)
+    gtk_tree_model_get_iter_first (sort_model, &siter);
+  else
+    {
+      GtkTreePath *path;
+
+      path = gtk_tree_path_new_from_string (parent_path);
+      gtk_tree_path_append_index (path, 0);
+
+      gtk_tree_model_get_iter (sort_model, &siter, path);
+
+      gtk_tree_path_free (path);
+    }
+
+  if (sort_order == GTK_SORT_ASCENDING)
+    prev_value = -1;
+  else
+    prev_value = INT_MAX;
+
+  do
+    {
+      int value;
+
+      gtk_tree_model_get (sort_model, &siter, 0, &value, -1);
+      if (sort_order == GTK_SORT_ASCENDING)
+        g_assert (prev_value <= value);
+      else
+        g_assert (prev_value >= value);
+
+      prev_value = value;
+    }
+  while (gtk_tree_model_iter_next (sort_model, &siter));
+}
+
+static void
+rows_reordered_single_level (void)
+{
+  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+  SignalMonitor *monitor;
+  GtkTreePath *path;
+  GType column_types[] = { G_TYPE_INT };
+  int order[][5] =
+    {
+        { 2, 3, 0, 1, 4 },
+        { 4, 3, 2, 1, 0 },
+        { 2, 1, 4, 3, 0 }
+    };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
+                                     0, 30, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
+                                     0, 40, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
+                                     0, 10, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
+                                     0, 20, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
+                                     0, 60, -1);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  monitor = signal_monitor_new (sort_model);
+
+  /* Sort */
+  path = gtk_tree_path_new ();
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          path, order[0], 5);
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_ASCENDING);
+  signal_monitor_assert_is_empty (monitor);
+  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
+
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          path, order[1], 5);
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_DESCENDING);
+  signal_monitor_assert_is_empty (monitor);
+  check_sort_order (sort_model, GTK_SORT_DESCENDING, NULL);
+
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          path, order[2], 5);
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+                                        GTK_SORT_ASCENDING);
+  signal_monitor_assert_is_empty (monitor);
+
+  gtk_tree_path_free (path);
+  signal_monitor_free (monitor);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (sort_model);
+
+  assert_entire_model_unreferenced (ref_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+rows_reordered_two_levels (void)
+{
+  GtkTreeIter iter1, iter2, iter3, iter4, iter5;
+  GtkTreeIter citer1, citer2, citer3, citer4, citer5;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+  SignalMonitor *monitor;
+  GtkTreePath *path, *child_path;
+  GType column_types[] = { G_TYPE_INT };
+  int order[][5] =
+    {
+        { 2, 3, 0, 1, 4 },
+        { 4, 3, 2, 1, 0 },
+        { 2, 1, 4, 3, 0 }
+    };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
+                                     0, 30, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
+                                     0, 40, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
+                                     0, 10, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
+                                     0, 20, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
+                                     0, 60, -1);
+
+  /* Child level */
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer1, &iter1, 0,
+                                     0, 30, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer2, &iter1, 1,
+                                     0, 40, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer3, &iter1, 2,
+                                     0, 10, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer4, &iter1, 3,
+                                     0, 20, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer5, &iter1, 4,
+                                     0, 60, -1);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
+
+  monitor = signal_monitor_new (sort_model);
+
+  /* Sort */
+  path = gtk_tree_path_new ();
+  child_path = gtk_tree_path_new_from_indices (2, -1);
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          path, order[0], 5);
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          child_path, order[0], 5);
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_ASCENDING);
+  signal_monitor_assert_is_empty (monitor);
+  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
+  /* The parent node of the child level moved due to sorting */
+  check_sort_order (sort_model, GTK_SORT_ASCENDING, "2");
+
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          path, order[1], 5);
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          child_path, order[1], 5);
+  gtk_tree_path_free (child_path);
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_DESCENDING);
+  signal_monitor_assert_is_empty (monitor);
+  check_sort_order (sort_model, GTK_SORT_DESCENDING, NULL);
+  /* The parent node of the child level moved due to sorting */
+  check_sort_order (sort_model, GTK_SORT_DESCENDING, "2");
+
+  child_path = gtk_tree_path_new_from_indices (0, -1);
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          path, order[2], 5);
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          child_path, order[2], 5);
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+                                        GTK_SORT_ASCENDING);
+  signal_monitor_assert_is_empty (monitor);
+
+  gtk_tree_path_free (path);
+  gtk_tree_path_free (child_path);
+  signal_monitor_free (monitor);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (sort_model);
+
+  g_object_unref (ref_model);
+}
+
+static void
+sorted_insert (void)
+{
+  GtkTreeIter iter1, iter2, iter3, iter4, iter5, new_iter;
+  GtkTreeModel *model;
+  GtkTreeModelRefCount *ref_model;
+  GtkTreeModel *sort_model;
+  GtkWidget *tree_view;
+  SignalMonitor *monitor;
+  GtkTreePath *path;
+  GType column_types[] = { G_TYPE_INT };
+  int order0[] = { 1, 2, 3, 0, 4, 5, 6 };
+
+  model = gtk_tree_model_ref_count_new ();
+  ref_model = GTK_TREE_MODEL_REF_COUNT (model);
+
+  gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
+                                   column_types);
+
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
+                                     0, 30, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
+                                     0, 40, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
+                                     0, 10, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
+                                     0, 20, -1);
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
+                                     0, 60, -1);
+
+  sort_model = gtk_tree_model_sort_new_with_model (model);
+  tree_view = gtk_tree_view_new_with_model (sort_model);
+
+  /* Sort */
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_ASCENDING);
+  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
+
+  monitor = signal_monitor_new (sort_model);
+
+  /* Insert a new item */
+  signal_monitor_append_signal (monitor, ROW_INSERTED, "4");
+  gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &new_iter, NULL,
+                                     5, 0, 50, -1);
+  signal_monitor_assert_is_empty (monitor);
+  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
+
+  /* Sort the tree sort and append a new item */
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
+                                        0, GTK_SORT_ASCENDING);
+  check_sort_order (model, GTK_SORT_ASCENDING, NULL);
+
+  path = gtk_tree_path_new ();
+  signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
+  signal_monitor_append_signal_reordered (monitor,
+                                          ROWS_REORDERED,
+                                          path, order0, 7);
+  signal_monitor_append_signal (monitor, ROW_CHANGED, "3");
+  gtk_tree_store_append (GTK_TREE_STORE (model), &new_iter, NULL);
+  gtk_tree_store_set (GTK_TREE_STORE (model), &new_iter, 0, 35, -1);
+  check_sort_order (model, GTK_SORT_ASCENDING, NULL);
+  check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
+
+  gtk_tree_path_free (path);
+  signal_monitor_free (monitor);
+
+  gtk_widget_destroy (tree_view);
+  g_object_unref (sort_model);
+
+  g_object_unref (ref_model);
+}
+
+
+static void
+specific_bug_300089 (void)
+{
+  /* Test case for GNOME Bugzilla bug 300089.  Written by
+   * Matthias Clasen.
+   */
+  GtkTreeModel *sort_model, *child_model;
+  GtkTreePath *path;
+  GtkTreeIter iter, iter2, sort_iter;
+
+  g_test_bug ("300089");
+
+  child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
+
+  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
+  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
+  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
+  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "B", -1);
+
+  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
+  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "D", -1);
+  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
+  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "E", -1);
+
+  gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
+  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "C", -1);
+
+
+  sort_model = GTK_TREE_MODEL (gtk_tree_model_sort_new_with_model (child_model));
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+                                        0, GTK_SORT_ASCENDING);
+
+  path = gtk_tree_path_new_from_indices (1, 1, -1);
+
+  /* make sure a level is constructed */
+  gtk_tree_model_get_iter (sort_model, &sort_iter, path);
+
+  /* change the "E" row in a way that causes it to change position */ 
+  gtk_tree_model_get_iter (child_model, &iter, path);
+  gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+specific_bug_364946 (void)
+{
+  /* This is a test case for GNOME Bugzilla bug 364946.  It was written
+   * by Andreas Koehler.
+   */
+  GtkTreeStore *store;
+  GtkTreeIter a, aa, aaa, aab, iter;
+  GtkTreeModel *s_model;
+
+  g_test_bug ("364946");
+
+  store = gtk_tree_store_new (1, G_TYPE_STRING);
+
+  gtk_tree_store_append (store, &a, NULL);
+  gtk_tree_store_set (store, &a, 0, "0", -1);
+
+  gtk_tree_store_append (store, &aa, &a);
+  gtk_tree_store_set (store, &aa, 0, "0:0", -1);
+
+  gtk_tree_store_append (store, &aaa, &aa);
+  gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
+
+  gtk_tree_store_append (store, &aab, &aa);
+  gtk_tree_store_set (store, &aab, 0, "0:0:1", -1);
+
+  s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model), 0,
+                                        GTK_SORT_ASCENDING);
+
+  gtk_tree_model_get_iter_from_string (s_model, &iter, "0:0:0");
+
+  gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
+  gtk_tree_store_remove (store, &aaa);
+  gtk_tree_store_remove (store, &aab);
+
+  gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model));
+}
+
+static void
+iter_test (GtkTreeModel *model)
+{
+  GtkTreeIter a, b;
+
+  g_assert (gtk_tree_model_get_iter_first (model, &a));
+
+  g_assert (gtk_tree_model_iter_next (model, &a));
+  g_assert (gtk_tree_model_iter_next (model, &a));
+  b = a;
+  g_assert (!gtk_tree_model_iter_next (model, &b));
+
+  g_assert (gtk_tree_model_iter_previous (model, &a));
+  g_assert (gtk_tree_model_iter_previous (model, &a));
+  b = a;
+  g_assert (!gtk_tree_model_iter_previous (model, &b));
+}
+
+static void
+specific_bug_674587 (void)
+{
+  GtkListStore *l;
+  GtkTreeStore *t;
+  GtkTreeModel *m;
+  GtkTreeIter a;
+
+  l = gtk_list_store_new (1, G_TYPE_STRING);
+
+  gtk_list_store_append (l, &a);
+  gtk_list_store_set (l, &a, 0, "0", -1);
+  gtk_list_store_append (l, &a);
+  gtk_list_store_set (l, &a, 0, "1", -1);
+  gtk_list_store_append (l, &a);
+  gtk_list_store_set (l, &a, 0, "2", -1);
+
+  iter_test (GTK_TREE_MODEL (l));
+
+  g_object_unref (l);
+
+  t = gtk_tree_store_new (1, G_TYPE_STRING);
+
+  gtk_tree_store_append (t, &a, NULL);
+  gtk_tree_store_set (t, &a, 0, "0", -1);
+  gtk_tree_store_append (t, &a, NULL);
+  gtk_tree_store_set (t, &a, 0, "1", -1);
+  gtk_tree_store_append (t, &a, NULL);
+  gtk_tree_store_set (t, &a, 0, "2", -1);
+
+  iter_test (GTK_TREE_MODEL (t));
+
+  m = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (t));
+
+  iter_test (m);
+
+  g_object_unref (t);
+  g_object_unref (m);
+}
+
+static void
+row_deleted_cb (GtkTreeModel *tree_model,
+    GtkTreePath  *path,
+    guint *count)
+{
+  *count = *count + 1;
+}
+
+static void
+specific_bug_698846 (void)
+{
+  GtkListStore *store;
+  GtkTreeModel *sorted;
+  GtkTreeIter iter;
+  guint count = 0;
+
+  g_test_bug ("698846");
+
+  store = gtk_list_store_new (1, G_TYPE_STRING);
+  sorted = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
+
+  gtk_list_store_insert_with_values (store, &iter, 0, 0, "a", -1);
+  gtk_list_store_insert_with_values (store, &iter, 1, 0, "b", -1);
+
+  g_signal_connect (sorted, "row-deleted", G_CALLBACK (row_deleted_cb), &count);
+
+  gtk_list_store_clear (store);
+
+  g_assert_cmpuint (count, ==, 2);
+}
+
+/* main */
+
+void
+register_sort_model_tests (void)
+{
+  g_test_add_func ("/TreeModelSort/ref-count/single-level",
+                   ref_count_single_level);
+  g_test_add_func ("/TreeModelSort/ref-count/two-levels",
+                   ref_count_two_levels);
+  g_test_add_func ("/TreeModelSort/ref-count/three-levels",
+                   ref_count_three_levels);
+  g_test_add_func ("/TreeModelSort/ref-count/delete-row",
+                   ref_count_delete_row);
+  g_test_add_func ("/TreeModelSort/ref-count/cleanup",
+                   ref_count_cleanup);
+  g_test_add_func ("/TreeModelSort/ref-count/row-ref",
+                   ref_count_row_ref);
+  g_test_add_func ("/TreeModelSort/ref-count/reorder/single-level",
+                   ref_count_reorder_single);
+  g_test_add_func ("/TreeModelSort/ref-count/reorder/two-levels",
+                   ref_count_reorder_two);
+
+  g_test_add_func ("/TreeModelSort/rows-reordered/single-level",
+                   rows_reordered_single_level);
+  g_test_add_func ("/TreeModelSort/rows-reordered/two-levels",
+                   rows_reordered_two_levels);
+  g_test_add_func ("/TreeModelSort/sorted-insert",
+                   sorted_insert);
+
+  g_test_add_func ("/TreeModelSort/specific/bug-300089",
+                   specific_bug_300089);
+  g_test_add_func ("/TreeModelSort/specific/bug-364946",
+                   specific_bug_364946);
+  g_test_add_func ("/TreeModelSort/specific/bug-674587",
+                   specific_bug_674587);
+  g_test_add_func ("/TreeModelSort/specific/bug-698846",
+                   specific_bug_698846);
+}
+
diff --git a/testsuite/gtk/stylecontext.c b/testsuite/gtk/stylecontext.c
new file mode 100644 (file)
index 0000000..3435ce4
--- /dev/null
@@ -0,0 +1,359 @@
+#include <gtk/gtk.h>
+
+static void
+test_parse_selectors (void)
+{
+  GtkCssProvider *provider;
+  GError *error;
+  gboolean res;
+  gint i;
+  const gchar *valid[] = {
+    "* {}",
+    "E {}",
+    "E F {}",
+    "E > F {}",
+    "E#id {}",
+    "#id {}",
+    "tab:first-child {}",
+    "tab:last-child {}",
+    "tab:nth-child(first) {}",
+    "tab:nth-child(last) {}",
+    "tab:nth-child(even) {}",
+    "tab:nth-child(odd) {}",
+    "tab:sorted {}",
+    ".some-class {}",
+    ".some-class.another-class {}",
+    ".some-class .another-class {}",
+    "E * {}",
+    "E .class {}",
+    "E > .foo {}",
+    "E > #id {}",
+    "E:active {}",
+    "E:prelight {}",
+    "E:hover {}",
+    "E:selected {}",
+    "E:insensitive {}",
+    "E:inconsistent {}",
+    "E:focused {}",
+    "E:active:prelight {}",
+    "* > .notebook tab:first-child .label:focused {}",
+    "E, F {}",
+    "E, F /* comment here */ {}",
+    "E,/* comment here */ F {}",
+    "E1.e1_2 #T3_4 {}",
+    "E:first-child {}",
+    "E:last-child {}",
+    "E:nth-child(first) {}",
+    "E:nth-child(last) {}",
+    "E:nth-child(even) {}",
+    "E:nth-child(odd) {}",
+    "E:sorted {}",
+    "E:focused tab {}",
+     NULL
+  };
+
+  error = NULL;
+  for (i = 0; valid[i]; i++)
+    {
+      provider = gtk_css_provider_new ();
+      res = gtk_css_provider_load_from_data (provider, valid[i], -1, &error);
+      if (error)
+        g_print ("parsing '%s': got unexpected error: %s\n", valid[i], error->message);
+      g_assert_no_error (error);
+      g_assert (res);
+
+      g_object_unref (provider);
+   }
+}
+
+static void
+test_path (void)
+{
+  GtkWidgetPath *path;
+  GtkWidgetPath *path2;
+  gint pos;
+  GtkRegionFlags flags;
+
+  path = gtk_widget_path_new ();
+  g_assert_cmpint (gtk_widget_path_length (path), ==, 0);
+
+  pos = gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
+  g_assert_cmpint (pos, ==, 0);
+  g_assert_cmpint (gtk_widget_path_length (path), ==, 1);
+  g_assert (gtk_widget_path_iter_get_object_type (path, 0) == GTK_TYPE_WINDOW);
+  g_assert (gtk_widget_path_is_type (path, GTK_TYPE_WIDGET));
+  g_assert (gtk_widget_path_iter_get_name (path, 0) == NULL);
+
+  pos = gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
+  g_assert_cmpint (pos, ==, 1);
+  g_assert_cmpint (gtk_widget_path_length (path), ==, 2);
+  gtk_widget_path_iter_set_object_type (path, pos, GTK_TYPE_BUTTON);
+  g_assert (gtk_widget_path_is_type (path, GTK_TYPE_BUTTON));
+  g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WIDGET));
+  g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WINDOW));
+  g_assert (!gtk_widget_path_has_parent (path, GTK_TYPE_DIALOG));
+  g_assert (gtk_widget_path_iter_get_name (path, 1) == NULL);
+
+  gtk_widget_path_iter_set_name (path, 1, "name");
+  g_assert (gtk_widget_path_iter_has_name (path, 1, "name"));
+
+  gtk_widget_path_iter_add_class (path, 1, "class1");
+  gtk_widget_path_iter_add_class (path, 1, "class2");
+  g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
+  g_assert (gtk_widget_path_iter_has_class (path, 1, "class2"));
+  g_assert (!gtk_widget_path_iter_has_class (path, 1, "class3"));
+
+  path2 = gtk_widget_path_copy (path);
+  g_assert (gtk_widget_path_iter_has_class (path2, 1, "class1"));
+  g_assert (gtk_widget_path_iter_has_class (path2, 1, "class2"));
+  g_assert (!gtk_widget_path_iter_has_class (path2, 1, "class3"));
+  gtk_widget_path_free (path2);
+
+  gtk_widget_path_iter_remove_class (path, 1, "class2");
+  g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
+  g_assert (!gtk_widget_path_iter_has_class (path, 1, "class2"));
+  gtk_widget_path_iter_clear_classes (path, 1);
+  g_assert (!gtk_widget_path_iter_has_class (path, 1, "class1"));
+
+  gtk_widget_path_iter_add_region (path, 1, "tab", 0);
+  gtk_widget_path_iter_add_region (path, 1, "title", GTK_REGION_EVEN | GTK_REGION_FIRST);
+
+  g_assert (gtk_widget_path_iter_has_region (path, 1, "tab", &flags) &&
+            flags == 0);
+  g_assert (gtk_widget_path_iter_has_region (path, 1, "title", &flags) &&
+            flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
+  g_assert (!gtk_widget_path_iter_has_region (path, 1, "extension", NULL));
+
+  path2 = gtk_widget_path_copy (path);
+  g_assert (gtk_widget_path_iter_has_region (path2, 1, "tab", &flags) &&
+            flags == 0);
+  g_assert (gtk_widget_path_iter_has_region (path2, 1, "title", &flags) &&
+            flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
+  g_assert (!gtk_widget_path_iter_has_region (path2, 1, "extension", NULL));
+  gtk_widget_path_free (path2);
+
+  gtk_widget_path_free (path);
+}
+
+static void
+test_match (void)
+{
+  GtkStyleContext *context;
+  GtkWidgetPath *path;
+  GtkCssProvider *provider;
+  GError *error;
+  const gchar *data;
+  GdkRGBA color;
+  GdkRGBA expected;
+
+  error = NULL;
+  provider = gtk_css_provider_new ();
+
+  gdk_rgba_parse (&expected, "#fff");
+
+  context = gtk_style_context_new ();
+
+  path = gtk_widget_path_new ();
+  gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
+  gtk_widget_path_append_type (path, GTK_TYPE_BOX);
+  gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
+  gtk_widget_path_iter_set_name (path, 0, "mywindow");
+  gtk_widget_path_iter_add_class (path, 2, "button");
+  gtk_style_context_set_path (context, path);
+  gtk_widget_path_free (path);
+
+  gtk_style_context_add_provider (context,
+                                  GTK_STYLE_PROVIDER (provider),
+                                  GTK_STYLE_PROVIDER_PRIORITY_USER);
+
+  data = "* { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         "GtkButton { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         "GtkButton { color: #fff }\n"
+         "GtkWindow > GtkButton { color: #000 }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         ".button { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         "GtkButton { color: #000 }\n"
+         ".button { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         "GtkButton { color: #000 }\n"
+         "GtkWindow GtkButton { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         ".button { color: #000 }\n"
+         "GtkWindow .button { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         "* .button { color: #000 }\n"
+         "#mywindow .button { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         "GtkWindow .button { color: #000 }\n"
+         "GtkWindow#mywindow .button { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  data = "* { color: #f00 }\n"
+         "GtkWindow .button { color: #000 }\n"
+         "GObject .button { color: #fff }";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_invalidate (context);
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  g_object_unref (provider);
+  g_object_unref (context);
+}
+
+static void
+test_style_property (void)
+{
+  GtkStyleContext *context;
+  GtkWidgetPath *path;
+  GtkCssProvider *provider;
+  GError *error;
+  const gchar *data;
+  gint x;
+  GdkRGBA color;
+  GdkRGBA expected;
+
+  error = NULL;
+  provider = gtk_css_provider_new ();
+
+  context = gtk_style_context_new ();
+
+  path = gtk_widget_path_new ();
+  gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
+  gtk_widget_path_append_type (path, GTK_TYPE_BOX);
+  gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
+  gtk_style_context_set_path (context, path);
+  gtk_widget_path_free (path);
+  gtk_style_context_set_state (context, GTK_STATE_FLAG_PRELIGHT);
+
+  /* Since we set the prelight state on the context, we expect
+   * only the third selector to match, even though the second one
+   * has higher specificity, and the fourth one comes later.
+   *
+   * In particular, we want to verify that widget style properties and
+   * CSS properties follow the same matching rules, ie we expect
+   * color to be #003 and child-displacement-x to be 3.
+   */
+  data = "GtkButton:insensitive { color: #001; -GtkButton-child-displacement-x: 1 }\n"
+         "GtkBox GtkButton:selected { color: #002; -GtkButton-child-displacement-x: 2 }\n"
+         "GtkButton:prelight { color: #003; -GtkButton-child-displacement-x: 3 }\n"
+         "GtkButton:focused { color: #004; -GtkButton-child-displacement-x: 4 }\n";
+  gtk_css_provider_load_from_data (provider, data, -1, &error);
+  g_assert_no_error (error);
+  gtk_style_context_add_provider (context,
+                                  GTK_STYLE_PROVIDER (provider),
+                                  GTK_STYLE_PROVIDER_PRIORITY_USER);
+
+  gtk_style_context_invalidate (context);
+
+  gtk_style_context_get_color (context, GTK_STATE_FLAG_PRELIGHT, &color);
+  gdk_rgba_parse (&expected, "#003");
+  g_assert (gdk_rgba_equal (&color, &expected));
+
+  gtk_style_context_get_style (context, "child-displacement-x", &x, NULL);
+
+  g_assert_cmpint (x, ==, 3);
+
+  g_object_unref (provider);
+  g_object_unref (context);
+}
+
+static void
+test_basic_properties (void)
+{
+  GtkStyleContext *context;
+  GtkWidgetPath *path;
+  GdkRGBA *color;
+  GdkRGBA *bg_color;
+  PangoFontDescription *font;
+
+  context = gtk_style_context_new ();
+  path = gtk_widget_path_new ();
+  gtk_style_context_set_path (context, path);
+  gtk_widget_path_free (path);
+
+  gtk_style_context_get (context, 0,
+                         "color", &color,
+                         "background-color", &bg_color,
+                         "font", &font,
+                         NULL);
+  g_assert (color != NULL);
+  g_assert (bg_color != NULL);
+  g_assert (font != NULL);
+
+  gdk_rgba_free (color);
+  gdk_rgba_free (bg_color);
+  pango_font_description_free (font);
+
+  g_object_unref (context);
+}
+
+int
+main (int argc, char *argv[])
+{
+  gtk_init (NULL, NULL);
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/style/parse/selectors", test_parse_selectors);
+  g_test_add_func ("/style/path", test_path);
+  g_test_add_func ("/style/match", test_match);
+  g_test_add_func ("/style/style-property", test_style_property);
+  g_test_add_func ("/style/basic", test_basic_properties);
+
+  return g_test_run ();
+}
diff --git a/testsuite/gtk/templates.c b/testsuite/gtk/templates.c
new file mode 100644 (file)
index 0000000..32c1e68
--- /dev/null
@@ -0,0 +1,359 @@
+/* templates.c
+ * Copyright (C) 2013 Openismus GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Tristan Van Berkom <tristanvb@openismus.com>
+ */
+#include <gtk/gtk.h>
+
+#ifdef HAVE_UNIX_PRINT_WIDGETS
+#  include <gtk/gtkunixprint.h>
+#endif
+
+static gboolean
+main_loop_quit_cb (gpointer data)
+{
+  gtk_main_quit ();
+
+  return FALSE;
+}
+
+static void
+test_dialog_basic (void)
+{
+  GtkWidget *dialog;
+
+  dialog = gtk_dialog_new();
+  g_assert (GTK_IS_DIALOG (dialog));
+  g_assert (gtk_dialog_get_action_area (GTK_DIALOG (dialog)) != NULL);
+  g_assert (gtk_dialog_get_content_area (GTK_DIALOG (dialog)) != NULL);
+
+  gtk_widget_destroy (dialog);
+}
+
+static void
+test_dialog_override_property (void)
+{
+  GtkWidget *dialog;
+
+  dialog = g_object_new (GTK_TYPE_DIALOG,
+                        "type-hint", GDK_WINDOW_TYPE_HINT_UTILITY,
+                        NULL);
+  g_assert (GTK_IS_DIALOG (dialog));
+  g_assert (gtk_window_get_type_hint (GTK_WINDOW (dialog)) == GDK_WINDOW_TYPE_HINT_UTILITY);
+
+  gtk_widget_destroy (dialog);
+}
+
+static void
+test_message_dialog_basic (void)
+{
+  GtkWidget *dialog;
+
+  dialog = gtk_message_dialog_new (NULL, 0,
+                                  GTK_MESSAGE_INFO,
+                                  GTK_BUTTONS_CLOSE,
+                                  "Do it hard !");
+  g_assert (GTK_IS_DIALOG (dialog));
+  gtk_widget_destroy (dialog);
+}
+
+static void
+test_about_dialog_basic (void)
+{
+  GtkWidget *dialog;
+
+  dialog = gtk_about_dialog_new ();
+  g_assert (GTK_IS_ABOUT_DIALOG (dialog));
+  gtk_widget_destroy (dialog);
+}
+
+static void
+test_info_bar_basic (void)
+{
+  GtkWidget *infobar;
+
+  infobar = gtk_info_bar_new ();
+  g_assert (GTK_IS_INFO_BAR (infobar));
+  gtk_widget_destroy (infobar);
+}
+
+static void
+test_lock_button_basic (void)
+{
+  GtkWidget *button;
+  GPermission *permission;
+
+  permission = g_simple_permission_new (TRUE);
+  button = gtk_lock_button_new (permission);
+  g_assert (GTK_IS_LOCK_BUTTON (button));
+  gtk_widget_destroy (button);
+  g_object_unref (permission);
+}
+
+static void
+test_assistant_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_assistant_new ();
+  g_assert (GTK_IS_ASSISTANT (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_scale_button_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_scale_button_new (GTK_ICON_SIZE_MENU,
+                                0, 100, 10, NULL);
+  g_assert (GTK_IS_SCALE_BUTTON (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_volume_button_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_volume_button_new ();
+  g_assert (GTK_IS_VOLUME_BUTTON (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_statusbar_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_statusbar_new ();
+  g_assert (GTK_IS_STATUSBAR (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_app_chooser_widget_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_app_chooser_widget_new (NULL);
+  g_assert (GTK_IS_APP_CHOOSER_WIDGET (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_app_chooser_dialog_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_app_chooser_dialog_new_for_content_type (NULL, 0, "text/plain");
+  g_assert (GTK_IS_APP_CHOOSER_DIALOG (widget));
+
+  /* GtkAppChooserDialog bug, if destroyed before spinning 
+   * the main context then app_chooser_online_get_default_ready_cb()
+   * will be eventually called and segfault.
+   */
+  g_timeout_add (500, main_loop_quit_cb, NULL);
+  gtk_main();
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_color_chooser_dialog_basic (void)
+{
+  GtkWidget *widget;
+
+  /* This test also tests the internal GtkColorEditor widget */
+  widget = gtk_color_chooser_dialog_new (NULL, NULL);
+  g_assert (GTK_IS_COLOR_CHOOSER_DIALOG (widget));
+  gtk_widget_destroy (widget);
+}
+
+/* Avoid warnings from GVFS-RemoteVolumeMonitor */
+static gboolean
+ignore_gvfs_warning (const gchar *log_domain,
+                    GLogLevelFlags log_level,
+                    const gchar *message,
+                    gpointer user_data)
+{
+  if (g_strcmp0 (log_domain, "GVFS-RemoteVolumeMonitor") == 0)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+test_file_chooser_widget_basic (void)
+{
+  GtkWidget *widget;
+
+  /* This test also tests the internal GtkPathBar widget */
+  g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
+
+  widget = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+  g_assert (GTK_IS_FILE_CHOOSER_WIDGET (widget));
+
+  /* XXX BUG:
+   *
+   * Spin the mainloop for a bit, this allows the file operations
+   * to complete, GtkFileChooserDefault has a bug where it leaks
+   * GtkTreeRowReferences to the internal shortcuts_model
+   *
+   * Since we assert all automated children are finalized we
+   * can catch this
+   */
+  g_timeout_add (100, main_loop_quit_cb, NULL);
+  gtk_main();
+
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_file_chooser_dialog_basic (void)
+{
+  GtkWidget *widget;
+
+  g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
+
+  widget = gtk_file_chooser_dialog_new ("The Dialog", NULL,
+                                       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+                                       GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                       NULL);
+
+  g_assert (GTK_IS_FILE_CHOOSER_DIALOG (widget));
+  g_timeout_add (100, main_loop_quit_cb, NULL);
+  gtk_main();
+
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_file_chooser_button_basic (void)
+{
+  GtkWidget *widget;
+
+  g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
+
+  widget = gtk_file_chooser_button_new ("Choose a file !", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+  g_assert (GTK_IS_FILE_CHOOSER_BUTTON (widget));
+  g_timeout_add (100, main_loop_quit_cb, NULL);
+  gtk_main();
+
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_font_button_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_font_button_new ();
+  g_assert (GTK_IS_FONT_BUTTON (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_font_chooser_widget_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_font_chooser_widget_new ();
+  g_assert (GTK_IS_FONT_CHOOSER_WIDGET (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_font_chooser_dialog_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_font_chooser_dialog_new ("Choose a font !", NULL);
+  g_assert (GTK_IS_FONT_CHOOSER_DIALOG (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_recent_chooser_widget_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_recent_chooser_widget_new ();
+  g_assert (GTK_IS_RECENT_CHOOSER_WIDGET (widget));
+  gtk_widget_destroy (widget);
+}
+
+#ifdef HAVE_UNIX_PRINT_WIDGETS
+static void
+test_page_setup_unix_dialog_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_page_setup_unix_dialog_new ("Setup your Page !", NULL);
+  g_assert (GTK_IS_PAGE_SETUP_UNIX_DIALOG (widget));
+  gtk_widget_destroy (widget);
+}
+
+static void
+test_print_unix_dialog_basic (void)
+{
+  GtkWidget *widget;
+
+  widget = gtk_print_unix_dialog_new ("Go Print !", NULL);
+  g_assert (GTK_IS_PRINT_UNIX_DIALOG (widget));
+  gtk_widget_destroy (widget);
+}
+#endif
+
+int
+main (int argc, char **argv)
+{
+  /* initialize test program */
+  gtk_test_init (&argc, &argv);
+
+  /* This environment variable cooperates with gtk_widget_destroy()
+   * to assert that all automated compoenents are properly finalized
+   * when a given composite widget is destroyed.
+   */
+  g_assert (g_setenv ("GTK_WIDGET_ASSERT_COMPONENTS", "1", TRUE));
+
+  g_test_add_func ("/Template/GtkDialog/Basic", test_dialog_basic);
+  g_test_add_func ("/Template/GtkDialog/OverrideProperty", test_dialog_override_property);
+  g_test_add_func ("/Template/GtkMessageDialog/Basic", test_message_dialog_basic);
+  g_test_add_func ("/Template/GtkAboutDialog/Basic", test_about_dialog_basic);
+  g_test_add_func ("/Template/GtkInfoBar/Basic", test_info_bar_basic);
+  g_test_add_func ("/Template/GtkLockButton/Basic", test_lock_button_basic);
+  g_test_add_func ("/Template/GtkAssistant/Basic", test_assistant_basic);
+  g_test_add_func ("/Template/GtkScaleButton/Basic", test_scale_button_basic);
+  g_test_add_func ("/Template/GtkVolumeButton/Basic", test_volume_button_basic);
+  g_test_add_func ("/Template/GtkStatusBar/Basic", test_statusbar_basic);
+  g_test_add_func ("/Template/GtkAppChooserWidget/Basic", test_app_chooser_widget_basic);
+  g_test_add_func ("/Template/GtkAppChooserDialog/Basic", test_app_chooser_dialog_basic);
+  g_test_add_func ("/Template/GtkColorChooserDialog/Basic", test_color_chooser_dialog_basic);
+  g_test_add_func ("/Template/GtkFileChooserWidget/Basic", test_file_chooser_widget_basic);
+  g_test_add_func ("/Template/GtkFileChooserDialog/Basic", test_file_chooser_dialog_basic);
+  g_test_add_func ("/Template/GtkFileChooserButton/Basic", test_file_chooser_button_basic);
+  g_test_add_func ("/Template/GtkFontButton/Basic", test_font_button_basic);
+  g_test_add_func ("/Template/GtkFontChooserWidget/Basic", test_font_chooser_widget_basic);
+  g_test_add_func ("/Template/GtkFontChooserDialog/Basic", test_font_chooser_dialog_basic);
+  g_test_add_func ("/Template/GtkRecentChooserWidget/Basic", test_recent_chooser_widget_basic);
+
+#ifdef HAVE_UNIX_PRINT_WIDGETS
+  g_test_add_func ("/Template/UnixPrint/GtkPageSetupUnixDialog/Basic", test_page_setup_unix_dialog_basic);
+  g_test_add_func ("/Template/UnixPrint/GtkPrintUnixDialog/Basic", test_print_unix_dialog_basic);
+#endif
+
+  return g_test_run();
+}
diff --git a/testsuite/gtk/testing.c b/testsuite/gtk/testing.c
new file mode 100644 (file)
index 0000000..ed67615
--- /dev/null
@@ -0,0 +1,306 @@
+/* Gtk+ testing utilities
+ * Copyright (C) 2007 Imendio AB
+ * Authors: Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <string.h>
+#include <math.h>
+
+/* Use a keyval that requires Shift to be active (in typical layouts)
+ * like GDK_KEY_ampersand, which is '<shift>6'
+ */
+#define KEYVAL_THAT_REQUIRES_SHIFT GDK_KEY_ampersand
+
+
+/* --- test functions --- */
+static void
+test_button_clicks (void)
+{
+  int a = 0, b = 0, c = 0;
+  GtkWidget *window = gtk_test_display_button_window ("Test Window",
+                                                      "Test: gtk_test_widget_click",
+                                                      "IgnoreMe1", &a,
+                                                      "ClickMe", &b,
+                                                      "IgnoreMe2", &c,
+                                                      NULL);
+  GtkWidget *button = gtk_test_find_widget (window, "*Click*", GTK_TYPE_BUTTON);
+  gboolean simsuccess;
+  g_assert (button != NULL);
+  simsuccess = gtk_test_widget_click (button, 1, 0);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+  g_assert (a == 0);
+  g_assert (b > 0);
+  g_assert (c == 0);
+}
+
+static void
+test_button_keys (void)
+{
+  int a = 0, b = 0, c = 0;
+  GtkWidget *window = gtk_test_display_button_window ("Test Window",
+                                                      "Test: gtk_test_widget_send_key",
+                                                      "IgnoreMe1", &a,
+                                                      "ClickMe", &b,
+                                                      "IgnoreMe2", &c,
+                                                      NULL);
+  GtkWidget *button = gtk_test_find_widget (window, "*Click*", GTK_TYPE_BUTTON);
+  gboolean simsuccess;
+  g_assert (button != NULL);
+  gtk_widget_grab_focus (button);
+  g_assert (gtk_widget_has_focus (button));
+  simsuccess = gtk_test_widget_send_key (button, GDK_KEY_Return, 0);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+  g_assert (a == 0);
+  g_assert (b > 0);
+  g_assert (c == 0);
+}
+
+static gboolean
+store_last_key_release (GtkWidget   *widget,
+                        GdkEventKey *event,
+                        gpointer     user_data)
+{
+  *((gint *)user_data) = event->keyval;
+  return FALSE;
+}
+
+static void
+test_send_shift_key (void)
+{
+  GtkWidget *window = gtk_test_display_button_window ("Test Window",
+                                                      "Test: test_send_shift_key()",
+                                                      "IgnoreMe1", NULL,
+                                                      "SendMeKeys", NULL,
+                                                      "IgnoreMe2", NULL,
+                                                      NULL);
+  GtkWidget *button = gtk_test_find_widget (window, "SendMeKeys", GTK_TYPE_BUTTON);
+  gint last_key_release = 0;
+  gboolean simsuccess;
+  g_assert (button != NULL);
+  g_signal_connect (button, "key-release-event",
+                    G_CALLBACK (store_last_key_release),
+                    &last_key_release);
+  gtk_widget_grab_focus (button);
+  g_assert (gtk_widget_has_focus (button));
+  simsuccess = gtk_test_widget_send_key (button, KEYVAL_THAT_REQUIRES_SHIFT, 0 /*modifiers*/);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+  g_assert_cmpint (KEYVAL_THAT_REQUIRES_SHIFT, ==, last_key_release);
+}
+
+static void
+test_slider_ranges (void)
+{
+  GtkWidget *child;
+  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: gtk_test_warp_slider");
+  GtkWidget *hscale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
+                                                -50, +50, 5);
+
+  child = gtk_bin_get_child (GTK_BIN (window));
+  gtk_container_add (GTK_CONTAINER (child), hscale);
+  gtk_widget_show (hscale);
+  gtk_widget_show_now (window);
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+  gtk_test_slider_set_perc (hscale, 0.0);
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+  g_assert (gtk_test_slider_get_value (hscale) == -50);
+  gtk_test_slider_set_perc (hscale, 50.0);
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+  g_assert (fabs (gtk_test_slider_get_value (hscale)) < 0.0001);
+  gtk_test_slider_set_perc (hscale, 100.0);
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+  g_assert (gtk_test_slider_get_value (hscale) == +50.0);
+}
+
+static void
+test_text_access (void)
+{
+  const int N_WIDGETS = 3;
+  GtkWidget *widgets[N_WIDGETS];
+  int i = 0;
+  widgets[i++] = gtk_test_create_widget (GTK_TYPE_LABEL, NULL);
+  widgets[i++] = gtk_test_create_widget (GTK_TYPE_ENTRY, NULL);
+  widgets[i++] = gtk_test_create_widget (GTK_TYPE_TEXT_VIEW, NULL);
+  g_assert (i == N_WIDGETS);
+  for (i = 0; i < N_WIDGETS; i++)
+    gtk_test_text_set (widgets[i], "foobar");
+  for (i = 0; i < N_WIDGETS; i++)
+    {
+      gchar *text  = gtk_test_text_get (widgets[i]);
+      g_assert (strcmp (text, "foobar") == 0);
+      g_free (text);
+    }
+  for (i = 0; i < N_WIDGETS; i++)
+    gtk_test_text_set (widgets[i], "");
+  for (i = 0; i < N_WIDGETS; i++)
+    {
+      gchar *text  = gtk_test_text_get (widgets[i]);
+      g_assert (strcmp (text, "") == 0);
+      g_free (text);
+    }
+}
+
+static void
+test_xserver_sync (void)
+{
+  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: test_xserver_sync");
+  GtkWidget *darea = gtk_drawing_area_new ();
+  GtkWidget *child;
+  GdkWindow *gdk_window;
+  GTimer *gtimer = g_timer_new();
+  gint sync_is_slower = 0, repeat = 5;
+
+  child = gtk_bin_get_child (GTK_BIN (window));
+  //gdk_window = gtk_widget_get_window (darea);
+
+  gtk_widget_set_size_request (darea, 320, 200);
+  gtk_container_add (GTK_CONTAINER (child), darea);
+  gtk_widget_show (darea);
+  gtk_widget_show_now (window);
+
+  while (repeat--)
+    {
+      gint i, many = 200;
+      double nosync_time, sync_time;
+      cairo_t *cr;
+
+      while (gtk_events_pending ())
+        gtk_main_iteration ();
+      gdk_window = gtk_widget_get_window (darea);
+      cr = gdk_cairo_create (gdk_window);
+      cairo_set_source_rgba (cr, 0, 1, 0, 0.1);
+      /* run a number of consecutive drawing requests, just using drawing queue */
+      g_timer_start (gtimer);
+      for (i = 0; i < many; i++)
+        {
+          cairo_paint (cr);
+        }
+      g_timer_stop (gtimer);
+      nosync_time = g_timer_elapsed (gtimer, NULL);
+      gdk_flush();
+      while (gtk_events_pending ())
+        gtk_main_iteration ();
+      g_timer_start (gtimer);
+      /* run a number of consecutive drawing requests with intermediate drawing syncs */
+      for (i = 0; i < many; i++)
+        {
+          cairo_paint (cr);
+          gdk_test_render_sync (gdk_window);
+        }
+      g_timer_stop (gtimer);
+      sync_time = g_timer_elapsed (gtimer, NULL);
+      sync_is_slower += sync_time > nosync_time * 1.5;
+    }
+  g_timer_destroy (gtimer);
+  g_assert (sync_is_slower > 0);
+}
+
+static void
+test_spin_button_arrows (void)
+{
+  GtkWidget *child;
+  GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test: test_spin_button_arrows");
+  GtkWidget *spinner = gtk_spin_button_new_with_range (0, 100, 5);
+  gboolean simsuccess;
+  double oldval, newval;
+
+  gtk_window_set_has_resize_grip (GTK_WINDOW (window), FALSE);
+
+  child = gtk_bin_get_child (GTK_BIN (window));
+  gtk_container_add (GTK_CONTAINER (child), spinner);
+  gtk_widget_show (spinner);
+  gtk_widget_show_now (window);
+  gtk_test_slider_set_perc (spinner, 0);
+  /* check initial spinner value */
+  oldval = gtk_test_slider_get_value (spinner);
+  g_assert (oldval == 0);
+  /* check simple increment */
+  simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 1, TRUE);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
+    gtk_main_iteration ();
+  newval = gtk_test_slider_get_value (spinner);
+  g_assert (newval > oldval);
+  /* check maximum warp */
+  simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 3, TRUE);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
+    gtk_main_iteration ();
+  oldval = gtk_test_slider_get_value (spinner);
+  g_assert (oldval == 100);
+  /* check simple decrement */
+  oldval = gtk_test_slider_get_value (spinner);
+  simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 1, FALSE);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
+    gtk_main_iteration ();
+  newval = gtk_test_slider_get_value (spinner);
+  g_assert (newval < oldval);
+  /* check minimum warp */
+  simsuccess = gtk_test_spin_button_click (GTK_SPIN_BUTTON (spinner), 3, FALSE);
+  g_assert (simsuccess == TRUE);
+  while (gtk_events_pending ()) /* let spin button timeout/idle handlers update */
+    gtk_main_iteration ();
+  oldval = gtk_test_slider_get_value (spinner);
+  g_assert (oldval == 0);
+}
+
+static void
+test_statusbar_remove_all (void)
+{
+  GtkWidget *statusbar;
+
+  g_test_bug ("640487");
+
+  statusbar = gtk_statusbar_new ();
+  g_object_ref_sink (statusbar);
+
+  gtk_statusbar_push (GTK_STATUSBAR (statusbar), 1, "bla");
+  gtk_statusbar_push (GTK_STATUSBAR (statusbar), 1, "bla");
+  gtk_statusbar_remove_all (GTK_STATUSBAR (statusbar), 1);
+
+  g_object_unref (statusbar);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  gtk_test_init (&argc, &argv);
+  g_test_bug_base ("http://bugzilla.gnome.org/");
+  gtk_test_register_all_types();
+
+  g_test_add_func ("/tests/statusbar-remove-all", test_statusbar_remove_all);
+  g_test_add_func ("/ui-tests/text-access", test_text_access);
+  g_test_add_func ("/ui-tests/button-clicks", test_button_clicks);
+  g_test_add_func ("/ui-tests/keys-events", test_button_keys);
+  g_test_add_func ("/ui-tests/send-shift-key", test_send_shift_key);
+  g_test_add_func ("/ui-tests/slider-ranges", test_slider_ranges);
+  g_test_add_func ("/ui-tests/xserver-sync", test_xserver_sync);
+  g_test_add_func ("/ui-tests/spin-button-arrows", test_spin_button_arrows);
+
+  return g_test_run();
+}
diff --git a/testsuite/gtk/textbuffer.c b/testsuite/gtk/textbuffer.c
new file mode 100644 (file)
index 0000000..e26a5dd
--- /dev/null
@@ -0,0 +1,1341 @@
+/* testtextbuffer.c -- Simplistic test suite
+ * Copyright (C) 2000 Red Hat, Inc
+ * Author: Havoc Pennington
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include "gtk/gtktexttypes.h" /* Private header, for UNKNOWN_CHAR */
+
+static void
+gtk_text_iter_spew (const GtkTextIter *iter, const gchar *desc)
+{
+  g_print (" %20s: line %d / char %d / line char %d / line byte %d\n",
+           desc,
+           gtk_text_iter_get_line (iter),
+           gtk_text_iter_get_offset (iter),
+           gtk_text_iter_get_line_offset (iter),
+           gtk_text_iter_get_line_index (iter));
+}
+
+static void
+check_get_set_text (GtkTextBuffer *buffer,
+                    const char    *str)
+{
+  GtkTextIter start, end, iter;
+  char *text;
+  int n;
+  
+  gtk_text_buffer_set_text (buffer, str, -1);
+  if (gtk_text_buffer_get_char_count (buffer) != g_utf8_strlen (str, -1))
+    g_error ("Wrong number of chars (%d not %d)",
+             gtk_text_buffer_get_char_count (buffer),
+             (int) g_utf8_strlen (str, -1));
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+  text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
+  if (strcmp (text, str) != 0)
+    g_error ("Got '%s' as buffer contents", text);
+  g_free (text);
+
+  /* line char counts */
+  iter = start;
+  n = 0;
+  do
+    {
+      n += gtk_text_iter_get_chars_in_line (&iter);
+    }
+  while (gtk_text_iter_forward_line (&iter));
+
+  if (n != gtk_text_buffer_get_char_count (buffer))
+    g_error ("Sum of chars in lines is %d but buffer char count is %d",
+             n, gtk_text_buffer_get_char_count (buffer));
+
+  /* line byte counts */
+  iter = start;
+  n = 0;
+  do
+    {
+      n += gtk_text_iter_get_bytes_in_line (&iter);
+    }
+  while (gtk_text_iter_forward_line (&iter));
+
+  if (n != strlen (str))
+    g_error ("Sum of chars in lines is %d but buffer byte count is %d",
+             n, (int) strlen (str));
+  
+  gtk_text_buffer_set_text (buffer, "", -1);
+
+  n = gtk_text_buffer_get_line_count (buffer);
+  if (n != 1)
+    g_error ("%d lines, expected 1", n);
+
+  n = gtk_text_buffer_get_char_count (buffer);
+  if (n != 0)
+    g_error ("%d chars, expected 0", n);
+}
+
+static gint
+count_toggles_at_iter (GtkTextIter *iter,
+                       GtkTextTag  *of_tag)
+{
+  GSList *tags;
+  GSList *tmp;
+  gint count = 0;
+  
+  /* get toggle-ons and toggle-offs */
+  tags = gtk_text_iter_get_toggled_tags (iter, TRUE);
+  tags = g_slist_concat (tags,
+                         gtk_text_iter_get_toggled_tags (iter, FALSE));
+  
+  tmp = tags;
+  while (tmp != NULL)
+    {
+      if (of_tag == NULL)
+        ++count;
+      else if (of_tag == tmp->data)
+        ++count;
+      
+      tmp = g_slist_next (tmp);
+    }
+  
+  g_slist_free (tags);
+
+  return count;
+}
+
+static gint
+count_toggles_in_range_by_char (GtkTextBuffer     *buffer,
+                                GtkTextTag        *of_tag,
+                                const GtkTextIter *start,
+                                const GtkTextIter *end)
+{
+  GtkTextIter iter;
+  gint count = 0;
+  
+  iter = *start;
+  do
+    {
+      count += count_toggles_at_iter (&iter, of_tag);
+      if (!gtk_text_iter_forward_char (&iter))
+        {
+          /* end iterator */
+          count += count_toggles_at_iter (&iter, of_tag);
+          break;
+        }
+    }
+  while (gtk_text_iter_compare (&iter, end) <= 0);
+  
+  return count;
+}
+
+static gint
+count_toggles_in_buffer (GtkTextBuffer *buffer,
+                         GtkTextTag    *of_tag)
+{
+  GtkTextIter start, end;
+
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+
+  return count_toggles_in_range_by_char (buffer, of_tag, &start, &end);
+}
+
+static void
+check_specific_tag_in_range (GtkTextBuffer     *buffer,
+                             const gchar       *tag_name,
+                             const GtkTextIter *start,
+                             const GtkTextIter *end)
+{
+  GtkTextIter iter;
+  GtkTextTag *tag;
+  gboolean state;
+  gint count;
+  gint buffer_count;
+  gint last_offset;
+
+  if (gtk_text_iter_compare (start, end) > 0)
+    {
+      g_print ("  (inverted range for checking tags, skipping)\n");
+      return;
+    }
+  
+  tag = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer),
+                                   tag_name);
+
+  buffer_count = count_toggles_in_range_by_char (buffer, tag, start, end);
+  
+  state = FALSE;
+  count = 0;
+
+  last_offset = -1;
+  iter = *start;
+  if (gtk_text_iter_toggles_tag (&iter, tag) ||
+      gtk_text_iter_forward_to_tag_toggle (&iter, tag))
+    {
+      do
+        {
+          gint this_offset;
+          
+          ++count;
+
+          this_offset = gtk_text_iter_get_offset (&iter);
+
+          if (this_offset <= last_offset)
+            g_error ("forward_to_tag_toggle moved in wrong direction");
+
+          last_offset = this_offset;
+          
+          if (gtk_text_iter_begins_tag (&iter, tag))
+            {
+              if (state)
+                g_error ("Tag %p is already on, and was toggled on?", tag);
+              state = TRUE;
+            }          
+          else if (gtk_text_iter_ends_tag (&iter, tag))
+            {
+              if (!state)
+                g_error ("Tag %p toggled off, but wasn't toggled on?", tag);
+              state = FALSE;
+            }
+          else
+            g_error ("forward_to_tag_toggle went to a location without a toggle");
+        }
+      while (gtk_text_iter_forward_to_tag_toggle (&iter, tag) &&
+             gtk_text_iter_compare (&iter, end) <= 0);
+    }
+
+  if (count != buffer_count)
+    g_error ("Counted %d tags iterating by char, %d iterating forward by tag toggle\n",
+             buffer_count, count);
+  
+  state = FALSE;
+  count = 0;
+  
+  iter = *end;
+  last_offset = gtk_text_iter_get_offset (&iter);
+  if (gtk_text_iter_toggles_tag (&iter, tag) ||
+      gtk_text_iter_backward_to_tag_toggle (&iter, tag))
+    {
+      do
+        {
+          gint this_offset;
+          
+          ++count;
+
+          this_offset = gtk_text_iter_get_offset (&iter);
+          
+          if (this_offset >= last_offset)
+            g_error ("backward_to_tag_toggle moved in wrong direction");
+          
+          last_offset = this_offset;
+
+          if (gtk_text_iter_begins_tag (&iter, tag))
+            {
+              if (!state)
+                g_error ("Tag %p wasn't on when we got to the on toggle going backward?", tag);
+              state = FALSE;
+            }
+          else if (gtk_text_iter_ends_tag (&iter, tag))
+            {
+              if (state)
+                g_error ("Tag %p off toggle, but we were already inside a tag?", tag);
+              state = TRUE;
+            }
+          else
+            g_error ("backward_to_tag_toggle went to a location without a toggle");
+        }
+      while (gtk_text_iter_backward_to_tag_toggle (&iter, tag) &&
+             gtk_text_iter_compare (&iter, start) >= 0);
+    }
+
+  if (count != buffer_count)
+    g_error ("Counted %d tags iterating by char, %d iterating backward by tag toggle\n",
+             buffer_count, count);
+}
+
+static void
+check_specific_tag (GtkTextBuffer *buffer,
+                    const gchar   *tag_name)
+{
+  GtkTextIter start, end;
+
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+  check_specific_tag_in_range (buffer, tag_name, &start, &end);
+  gtk_text_iter_forward_chars (&start, 2);
+  gtk_text_iter_backward_chars (&end, 2);
+  if (gtk_text_iter_compare (&start, &end) < 0)
+    check_specific_tag_in_range (buffer, tag_name, &start, &end);
+}
+
+static void
+run_tests (GtkTextBuffer *buffer)
+{
+  GtkTextIter iter;
+  GtkTextIter start;
+  GtkTextIter end;
+  GtkTextIter mark;
+  gint i, j;
+  gint num_chars;
+  GtkTextMark *bar_mark;
+  GtkTextTag *tag;
+  GHashTable *tag_states;
+  gint count;
+  gint buffer_count;
+  
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+
+  /* Check that walking the tree via chars and via iterators produces
+   * the same number of indexable locations.
+   */
+  num_chars = gtk_text_buffer_get_char_count (buffer);
+  iter = start;
+  bar_mark = gtk_text_buffer_create_mark (buffer, "bar", &iter, FALSE);
+  i = 0;
+  while (i < num_chars)
+    {
+      GtkTextIter current;
+      GtkTextMark *foo_mark;
+
+      gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
+
+      if (!gtk_text_iter_equal (&iter, &current))
+        {
+          g_error ("get_char_index didn't return current iter");
+        }
+
+      j = gtk_text_iter_get_offset (&iter);
+
+      if (i != j)
+        {
+          g_error ("iter converted to %d not %d", j, i);
+        }
+
+      /* get/set mark */
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
+
+      if (!gtk_text_iter_equal (&iter, &mark))
+        {
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not moved to the right place.");
+        }
+
+      foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
+      gtk_text_buffer_delete_mark (buffer, foo_mark);
+
+      if (!gtk_text_iter_equal (&iter, &mark))
+        {
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not created in the right place.");
+        }
+
+      if (gtk_text_iter_is_end (&iter))
+        g_error ("iterators ran out before chars (offset %d of %d)",
+                 i, num_chars);
+
+      gtk_text_iter_forward_char (&iter);
+
+      gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
+
+      ++i;
+    }
+
+  if (!gtk_text_iter_equal (&iter, &end))
+    g_error ("Iterating over all chars didn't end with the end iter");
+
+  /* Do the tree-walk backward
+   */
+  num_chars = gtk_text_buffer_get_char_count (buffer);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1);
+
+  gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
+
+  i = num_chars;
+
+  if (!gtk_text_iter_equal (&iter, &end))
+    g_error ("iter at char -1 is not equal to the end iterator");
+
+  while (i >= 0)
+    {
+      GtkTextIter current;
+      GtkTextMark *foo_mark;
+
+      gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
+
+      if (!gtk_text_iter_equal (&iter, &current))
+        {
+          g_error ("get_char_index didn't return current iter while going backward");
+        }
+      j = gtk_text_iter_get_offset (&iter);
+
+      if (i != j)
+        {
+          g_error ("going backward, iter converted to %d not %d", j, i);
+        }
+
+      /* get/set mark */
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
+
+      if (!gtk_text_iter_equal (&iter, &mark))
+        {
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not moved to the right place.");
+        }
+
+      foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
+      gtk_text_buffer_delete_mark (buffer, foo_mark);
+
+      if (!gtk_text_iter_equal (&iter, &mark))
+        {
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not created in the right place.");
+        }
+
+      if (i > 0)
+        {
+          if (!gtk_text_iter_backward_char (&iter))
+            g_error ("iterators ran out before char indexes");
+
+          gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
+        }
+      else
+        {
+          if (gtk_text_iter_backward_char (&iter))
+            g_error ("went backward from 0?");
+        }
+
+      --i;
+    }
+
+  if (!gtk_text_iter_equal (&iter, &start))
+    g_error ("Iterating backward over all chars didn't end with the start iter");
+
+  /*
+   * Check that get_line_count returns the same number of lines
+   * as walking the tree by line
+   */
+  i = 1; /* include current (first) line */
+  gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
+  while (gtk_text_iter_forward_line (&iter))
+    ++i;
+
+  if (i != gtk_text_buffer_get_line_count (buffer))
+    g_error ("Counted %d lines, buffer has %d", i,
+             gtk_text_buffer_get_line_count (buffer));
+
+  /*
+   * Check that moving over tag toggles thinks about working.
+   */
+
+  buffer_count = count_toggles_in_buffer (buffer, NULL);
+  
+  tag_states = g_hash_table_new (NULL, NULL);
+  count = 0;
+  
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+  if (gtk_text_iter_toggles_tag (&iter, NULL) ||
+      gtk_text_iter_forward_to_tag_toggle (&iter, NULL))
+    {
+      do
+        {
+          GSList *tags;
+          GSList *tmp;
+          gboolean found_some = FALSE;
+          
+          /* get toggled-on tags */
+          tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
+
+          if (tags)
+            found_some = TRUE;
+          
+          tmp = tags;
+          while (tmp != NULL)
+            {
+              ++count;
+              
+              tag = tmp->data;
+              
+              if (g_hash_table_lookup (tag_states, tag))
+                g_error ("Tag %p is already on, and was toggled on?", tag);
+
+              g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
+          
+              tmp = g_slist_next (tmp);
+            }
+
+          g_slist_free (tags);
+      
+          /* get toggled-off tags */
+          tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
+
+          if (tags)
+            found_some = TRUE;
+          
+          tmp = tags;
+          while (tmp != NULL)
+            {
+              ++count;
+              
+              tag = tmp->data;
+
+              if (!g_hash_table_lookup (tag_states, tag))
+                g_error ("Tag %p is already off, and was toggled off?", tag);
+
+              g_hash_table_remove (tag_states, tag);
+          
+              tmp = g_slist_next (tmp);
+            }
+
+          g_slist_free (tags);
+
+          if (!found_some)
+            g_error ("No tags found going forward to tag toggle.");
+
+        }
+      while (gtk_text_iter_forward_to_tag_toggle (&iter, NULL));
+    }
+  
+  g_hash_table_destroy (tag_states);
+
+  if (count != buffer_count)
+    g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
+             buffer_count, count);
+  
+  /* Go backward; here TRUE in the hash means we saw
+   * an off toggle last.
+   */
+  
+  tag_states = g_hash_table_new (NULL, NULL);
+  count = 0;
+  
+  gtk_text_buffer_get_end_iter (buffer, &iter);
+  if (gtk_text_iter_toggles_tag (&iter, NULL) ||
+      gtk_text_iter_backward_to_tag_toggle (&iter, NULL))
+    {
+      do
+        {
+          GSList *tags;
+          GSList *tmp;
+          gboolean found_some = FALSE;
+          
+          /* get toggled-off tags */
+          tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
+
+          if (tags)
+            found_some = TRUE;
+          
+          tmp = tags;
+          while (tmp != NULL)
+            {
+              ++count;
+              
+              tag = tmp->data;
+
+              if (g_hash_table_lookup (tag_states, tag))
+                g_error ("Tag %p has two off-toggles in a row?", tag);
+          
+              g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
+          
+              tmp = g_slist_next (tmp);
+            }
+
+          g_slist_free (tags);
+      
+          /* get toggled-on tags */
+          tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
+
+          if (tags)
+            found_some = TRUE;
+          
+          tmp = tags;
+          while (tmp != NULL)
+            {
+              ++count;
+              
+              tag = tmp->data;
+
+              if (!g_hash_table_lookup (tag_states, tag))
+                g_error ("Tag %p was toggled on, but saw no off-toggle?", tag);
+
+              g_hash_table_remove (tag_states, tag);
+          
+              tmp = g_slist_next (tmp);
+            }
+
+          g_slist_free (tags);
+
+          if (!found_some)
+            g_error ("No tags found going backward to tag toggle.");
+        }
+      while (gtk_text_iter_backward_to_tag_toggle (&iter, NULL));
+    }
+  
+  g_hash_table_destroy (tag_states);
+
+  if (count != buffer_count)
+    g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
+             buffer_count, count);
+
+  check_specific_tag (buffer, "fg_red");
+  check_specific_tag (buffer, "bg_green");
+  check_specific_tag (buffer, "front_tag");
+  check_specific_tag (buffer, "center_tag");
+  check_specific_tag (buffer, "end_tag");
+}
+
+
+static const char  *book_closed_xpm[] = {
+"16 16 6 1",
+"       c None s None",
+".      c black",
+"X      c red",
+"o      c yellow",
+"O      c #808080",
+"#      c white",
+"                ",
+"       ..       ",
+"     ..XX.      ",
+"   ..XXXXX.     ",
+" ..XXXXXXXX.    ",
+".ooXXXXXXXXX.   ",
+"..ooXXXXXXXXX.  ",
+".X.ooXXXXXXXXX. ",
+".XX.ooXXXXXX..  ",
+" .XX.ooXXX..#O  ",
+"  .XX.oo..##OO. ",
+"   .XX..##OO..  ",
+"    .X.#OO..    ",
+"     ..O..      ",
+"      ..        ",
+"                "};
+
+static void
+fill_buffer (GtkTextBuffer *buffer)
+{
+  GtkTextTag *tag;
+  GdkColor color, color2;
+  GtkTextIter iter;
+  GtkTextIter iter2;
+  GdkPixbuf *pixbuf;
+  int i;
+
+  color.red = color.green = 0;
+  color.blue = 0xffff;
+  color2.red = 0xfff;
+  color2.blue = 0x0;
+  color2.green = 0;
+  
+  gtk_text_buffer_create_tag (buffer, "fg_blue",
+                              "foreground_gdk", &color,
+                              "background_gdk", &color2,
+                              "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
+                              NULL);
+
+  color.blue = color.green = 0;
+  color.red = 0xffff;
+  
+  gtk_text_buffer_create_tag (buffer, "fg_red",
+                              "rise", -4,
+                              "foreground_gdk", &color,
+                              NULL);
+
+  color.blue = color.red = 0;
+  color.green = 0xffff;
+  
+  gtk_text_buffer_create_tag (buffer, "bg_green",
+                              "background_gdk", &color,
+                              "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
+                              NULL);
+
+  pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
+
+  g_assert (pixbuf != NULL);
+
+  i = 0;
+  while (i < 10)
+    {
+      gchar *str;
+
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+
+      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
+
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
+
+      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
+
+      str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
+                            i);
+
+      gtk_text_buffer_insert (buffer, &iter, str, -1);
+
+      g_free (str);
+
+      gtk_text_buffer_insert (buffer, &iter,
+                              "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line\n\n"
+                              /* This is UTF8 stuff, Emacs doesn't
+                                 really know how to display it */
+                              "Spanish (Espa\303\261ol) \302\241Hola! / French (Fran\303\247ais) Bonjour, Salut / German (Deutsch S\303\274d) Gr\303\274\303\237 Gott (testing Latin-1 chars encoded in UTF8)\nThai (we can't display this, just making sure we don't crash)  (\340\270\240\340\270\262\340\270\251\340\270\262\340\271\204\340\270\227\340\270\242)  \340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\270\243\340\270\261\340\270\232, \340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\271\210\340\270\260\n",
+                              -1);
+
+      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
+      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
+
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
+
+      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
+
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
+
+      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
+
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
+
+      gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
+
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
+      iter2 = iter;
+      gtk_text_iter_forward_chars (&iter2, 10);
+
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
+
+      gtk_text_iter_forward_chars (&iter, 7);
+      gtk_text_iter_forward_chars (&iter2, 10);
+
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
+
+      gtk_text_iter_forward_chars (&iter, 12);
+      gtk_text_iter_forward_chars (&iter2, 10);
+
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
+
+      gtk_text_iter_forward_chars (&iter, 10);
+      gtk_text_iter_forward_chars (&iter2, 15);
+
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
+
+      gtk_text_iter_forward_chars (&iter, 20);
+      gtk_text_iter_forward_chars (&iter2, 20);
+
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
+
+      gtk_text_iter_backward_chars (&iter, 25);
+      gtk_text_iter_forward_chars (&iter2, 5);
+
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
+
+      gtk_text_iter_forward_chars (&iter, 15);
+      gtk_text_iter_backward_chars (&iter2, 10);
+
+      gtk_text_buffer_remove_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_remove_tag_by_name (buffer, "fg_blue", &iter, &iter2);
+
+      ++i;
+    }
+
+  /* Put in tags that are just at the beginning, and just near the end,
+   * and just near the middle.
+   */
+  tag = gtk_text_buffer_create_tag (buffer, "front_tag", NULL);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter2, 300);
+
+  gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);  
+  
+  tag = gtk_text_buffer_create_tag (buffer, "end_tag", NULL);
+  gtk_text_buffer_get_end_iter (buffer, &iter2);
+  gtk_text_iter_backward_chars (&iter2, 12);
+  iter = iter2;
+  gtk_text_iter_backward_chars (&iter, 157);
+
+  gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
+  
+  tag = gtk_text_buffer_create_tag (buffer, "center_tag", NULL);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter,
+                                      gtk_text_buffer_get_char_count (buffer)/2);
+  gtk_text_iter_backward_chars (&iter, 37);
+  iter2 = iter;
+  gtk_text_iter_forward_chars (&iter2, 57);
+
+  gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);  
+
+  g_object_unref (pixbuf);
+}
+
+
+/*
+ * Line separator tests (initially to avoid regression on bugzilla #57428)
+ */
+
+static void
+test_line_separation (const char* str,
+                      gboolean    expect_next_line,
+                      gboolean    expect_end_iter,
+                      int         expected_line_count,
+                      int         expected_line_break,
+                      int         expected_next_line_start)
+{
+  GtkTextIter iter;
+  GtkTextBuffer* buffer;
+  gboolean on_next_line;
+  gboolean on_end_iter;
+  gint new_pos;
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  gtk_text_buffer_set_text (buffer, str, -1);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, expected_line_break);
+
+  g_assert (gtk_text_iter_ends_line (&iter) || gtk_text_iter_is_end (&iter));
+
+  g_assert (gtk_text_buffer_get_line_count (buffer) == expected_line_count);
+  
+  on_next_line = gtk_text_iter_forward_line (&iter);
+
+  g_assert (expect_next_line == on_next_line);
+
+  on_end_iter = gtk_text_iter_is_end (&iter);
+
+  g_assert (on_end_iter == expect_end_iter);
+  
+  new_pos = gtk_text_iter_get_offset (&iter);
+    
+  if (on_next_line)
+    g_assert (expected_next_line_start == new_pos);
+
+  ++expected_line_break;
+  while (expected_line_break < expected_next_line_start)
+    {
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, expected_line_break);
+
+      g_assert (!gtk_text_iter_ends_line (&iter));
+
+      on_next_line = gtk_text_iter_forward_line (&iter);
+        
+      g_assert (expect_next_line == on_next_line);
+        
+      new_pos = gtk_text_iter_get_offset (&iter);
+        
+      if (on_next_line)
+        g_assert (expected_next_line_start == new_pos);
+        
+      ++expected_line_break;
+    }
+
+  /* FIXME tests for backward line */
+  
+  g_object_unref (buffer);
+}
+
+/* there are cases where \r and \n should not be treated like \r\n,
+ * originally bug #337022. */
+static void
+split_r_n_separators_test (void)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter iter;
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  gtk_text_buffer_set_text (buffer, "foo\ra\nbar\n", -1);
+
+  /* delete 'a' so that we have
+
+     1 foo\r
+     2 \n
+     3 bar\n
+
+   * and both \r and \n are line separators */
+
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 5);
+  gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
+
+  g_assert (gtk_text_iter_ends_line (&iter));
+
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3);
+  g_assert (gtk_text_iter_ends_line (&iter));
+
+  g_object_unref (buffer);
+}
+
+static void
+test_line_separator (void)
+{
+  char *str;
+  char buf[7] = { '\0', };
+
+  /* Only one character has type G_UNICODE_PARAGRAPH_SEPARATOR in
+   * Unicode 3.0; update this if that changes.
+   */
+#define PARAGRAPH_SEPARATOR 0x2029
+  
+  test_line_separation ("line", FALSE, TRUE, 1, 4, 4);
+  test_line_separation ("line\r\n", FALSE, TRUE, 2, 4, 6);
+  test_line_separation ("line\r", FALSE, TRUE, 2, 4, 5);
+  test_line_separation ("line\n", FALSE, TRUE, 2, 4, 5);
+  test_line_separation ("line\rqw", TRUE, FALSE, 2, 4, 5);
+  test_line_separation ("line\nqw", TRUE, FALSE, 2, 4, 5);
+  test_line_separation ("line\r\nqw", TRUE, FALSE, 2, 4, 6);
+  
+  g_unichar_to_utf8 (PARAGRAPH_SEPARATOR, buf);
+  
+  str = g_strdup_printf ("line%s", buf);
+  test_line_separation (str, FALSE, TRUE, 2, 4, 5);
+  g_free (str);
+  str = g_strdup_printf ("line%sqw", buf);
+  test_line_separation (str, TRUE, FALSE, 2, 4, 5);
+  g_free (str);
+
+  split_r_n_separators_test ();
+}
+
+static void
+test_backspace (void)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter iter;
+  gboolean ret;
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  gtk_text_buffer_set_text (buffer, "foo", -1);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 2);
+  ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
+  g_assert (ret);
+  g_assert_cmpint (1, ==, gtk_text_iter_get_offset (&iter));
+  g_assert_cmpint (2, ==, gtk_text_buffer_get_char_count (buffer));
+
+  gtk_text_buffer_set_text (buffer, "foo", -1);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+  ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
+  g_assert (!ret);
+  g_assert_cmpint (0, ==, gtk_text_iter_get_offset (&iter));
+  g_assert_cmpint (3, ==, gtk_text_buffer_get_char_count (buffer));
+
+  /* test bug #544724 */
+  gtk_text_buffer_set_text (buffer, "foo\r\n\r\nbar", -1);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 5);
+  ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
+  g_assert (ret);
+  g_assert_cmpint (0, ==, gtk_text_iter_get_line (&iter));
+  g_assert_cmpint (8, ==, gtk_text_buffer_get_char_count (buffer));
+
+  g_object_unref (buffer);
+}
+
+static void
+test_logical_motion (void)
+{
+  char *str;
+  char buf1[7] = { '\0', };
+  char buf2[7] = { '\0', };
+  char buf3[7] = { '\0', };
+  int expected[30];
+  int expected_steps;
+  int i;
+  GtkTextBuffer *buffer;
+  GtkTextIter iter;
+  
+  buffer = gtk_text_buffer_new (NULL);
+  
+#define LEADING_JAMO 0x1111
+#define VOWEL_JAMO 0x1167
+#define TRAILING_JAMO 0x11B9
+  
+  g_unichar_to_utf8 (LEADING_JAMO, buf1);
+  g_unichar_to_utf8 (VOWEL_JAMO, buf2);
+  g_unichar_to_utf8 (TRAILING_JAMO, buf3);
+
+  /* Build the string "abc<leading><vowel><trailing>def\r\nxyz" */
+  str = g_strconcat ("abc", buf1, buf2, buf3, "def\r\nxyz", NULL);
+  gtk_text_buffer_set_text (buffer, str, -1);
+  g_free (str);
+  
+  /* Check cursor positions */
+  memset (expected, 0, sizeof (expected));
+  expected[0] = 0;    /* before 'a' */
+  expected[1] = 1;    /* before 'b' */
+  expected[2] = 2;    /* before 'c' */
+  expected[3] = 3;    /* before jamo */
+  expected[4] = 6;    /* before 'd' */
+  expected[5] = 7;    /* before 'e' */
+  expected[6] = 8;    /* before 'f' */
+  expected[7] = 9;    /* before '\r' */
+  expected[8] = 11;   /* before 'x' */
+  expected[9] = 12;   /* before 'y' */
+  expected[10] = 13;  /* before 'z' */
+  expected[11] = 14;  /* after 'z' (only matters going backward) */
+  expected_steps = 11;
+  
+  gtk_text_buffer_get_start_iter (buffer, &iter);
+  i = 0;
+  do
+    {
+      int pos;
+
+      pos = gtk_text_iter_get_offset (&iter);
+      
+      if (pos != expected[i])
+        {
+          g_error ("Cursor position %d, expected %d",
+                   pos, expected[i]);
+        }
+
+      ++i;      
+    }
+  while (gtk_text_iter_forward_cursor_position (&iter));
+
+  if (!gtk_text_iter_is_end (&iter))
+    g_error ("Expected to stop at the end iterator\n");
+
+  if (!gtk_text_iter_is_cursor_position (&iter))
+    g_error ("Should be a cursor position before the end iterator");
+  
+  if (i != expected_steps)
+    g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
+
+  i = expected_steps;
+  do
+    {
+      int pos;
+
+      pos = gtk_text_iter_get_offset (&iter);
+      
+      if (pos != expected[i])
+        {
+          g_error ("Moving backward, cursor position %d, expected %d",
+                   pos, expected[i]);
+        }
+
+      /* g_print ("%d = %d\n", pos, expected[i]); */
+      
+      --i;
+    }
+  while (gtk_text_iter_backward_cursor_position (&iter));
+
+  if (i != -1)
+    g_error ("Expected %d steps, there were actually %d\n", expected_steps - i, i);
+
+  if (!gtk_text_iter_is_start (&iter))
+    g_error ("Expected to stop at the start iterator\n");
+
+
+  /* Check sentence boundaries */
+  
+  gtk_text_buffer_set_text (buffer, "Hi.\nHi. \nHi! Hi. Hi? Hi.", -1);
+
+  memset (expected, 0, sizeof (expected));
+
+  expected[0] = 0;    /* before first Hi */
+  expected[1] = 3;    /* After first . */
+  expected[2] = 7;    /* After second . */
+  expected[3] = 12;   /* After ! */
+  expected[4] = 16;   /* After third . */
+  expected[5] = 20;   /* After ? */
+  
+  expected_steps = 6;
+  
+  gtk_text_buffer_get_start_iter (buffer, &iter);
+  i = 0;
+  do
+    {
+      int pos;
+
+      pos = gtk_text_iter_get_offset (&iter);
+
+      if (pos != expected[i])
+        {
+          g_error ("Sentence position %d, expected %d",
+                   pos, expected[i]);
+        }
+
+      if (i != 0 &&
+          !gtk_text_iter_is_end (&iter) &&
+          !gtk_text_iter_ends_sentence (&iter))
+        g_error ("Iterator at %d should end a sentence", pos);
+      
+      ++i;
+    }
+  while (gtk_text_iter_forward_sentence_end (&iter));
+
+  if (i != expected_steps)
+    g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
+
+  if (!gtk_text_iter_is_end (&iter))
+    g_error ("Expected to stop at the end iterator\n");
+  
+  gtk_text_buffer_set_text (buffer, "Hi.\nHi. \nHi! Hi. Hi? Hi.", -1);
+
+  memset (expected, 0, sizeof (expected));
+
+  expected[0] = 24;
+  expected[1] = 21;
+  expected[2] = 17;
+  expected[3] = 13;
+  expected[4] = 9;
+  expected[5] = 4;
+  expected[6] = 0;
+  
+  expected_steps = 7;
+  
+  gtk_text_buffer_get_end_iter (buffer, &iter);
+  i = 0;
+  do
+    {
+      int pos;
+
+      pos = gtk_text_iter_get_offset (&iter);
+
+      if (pos != expected[i])
+        {
+          g_error ("Sentence position %d, expected %d",
+                   pos, expected[i]);
+        }
+
+      if (pos != 0 &&
+          !gtk_text_iter_is_end (&iter) &&
+          !gtk_text_iter_starts_sentence (&iter))
+        g_error ("Iterator at %d should start a sentence", pos);
+      
+      ++i;
+    }
+  while (gtk_text_iter_backward_sentence_start (&iter));
+
+  if (i != expected_steps)
+    g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
+
+  if (gtk_text_iter_get_offset (&iter) != 0)
+    g_error ("Expected to stop at the start iterator\n");
+  
+  g_object_unref (buffer);
+}
+
+static void
+test_marks (void)
+{
+  GtkTextBuffer *buf1, *buf2;
+  GtkTextMark *mark;
+  GtkTextIter iter;
+
+  buf1 = gtk_text_buffer_new (NULL);
+  buf2 = gtk_text_buffer_new (NULL);
+
+  gtk_text_buffer_get_start_iter (buf1, &iter);
+  mark = gtk_text_buffer_create_mark (buf1, "foo", &iter, TRUE);
+  g_object_ref (mark);
+  gtk_text_mark_set_visible (mark, TRUE);
+  gtk_text_buffer_delete_mark (buf1, mark);
+
+  g_assert (gtk_text_mark_get_visible (mark));
+  g_assert (gtk_text_mark_get_left_gravity (mark));
+  g_assert (!strcmp ("foo", gtk_text_mark_get_name (mark)));
+  g_assert (gtk_text_mark_get_buffer (mark) == NULL);
+  g_assert (gtk_text_mark_get_deleted (mark));
+  g_assert (gtk_text_buffer_get_mark (buf1, "foo") == NULL);
+
+  gtk_text_buffer_get_start_iter (buf2, &iter);
+  gtk_text_buffer_add_mark (buf2, mark, &iter);
+  gtk_text_buffer_insert (buf2, &iter, "ewfwefwefwe", -1);
+  gtk_text_buffer_get_iter_at_mark (buf2, &iter, mark);
+
+  g_assert (gtk_text_mark_get_visible (mark));
+  g_assert (gtk_text_iter_is_start (&iter));
+  g_assert (gtk_text_mark_get_left_gravity (mark));
+  g_assert (!strcmp ("foo", gtk_text_mark_get_name (mark)));
+  g_assert (gtk_text_mark_get_buffer (mark) == buf2);
+  g_assert (!gtk_text_mark_get_deleted (mark));
+  g_assert (gtk_text_buffer_get_mark (buf2, "foo") == mark);
+
+  gtk_text_buffer_delete_mark (buf2, mark);
+  gtk_text_mark_set_visible (mark, FALSE);
+  g_object_unref (mark);
+
+  mark = gtk_text_mark_new ("blah", TRUE);
+  gtk_text_buffer_get_start_iter (buf1, &iter);
+  gtk_text_mark_set_visible (mark, TRUE);
+  gtk_text_buffer_add_mark (buf1, mark, &iter);
+
+  g_assert (gtk_text_mark_get_visible (mark));
+  g_assert (gtk_text_mark_get_buffer (mark) == buf1);
+  g_assert (!gtk_text_mark_get_deleted (mark));
+  g_assert (gtk_text_buffer_get_mark (buf1, "blah") == mark);
+  g_assert (!strcmp ("blah", gtk_text_mark_get_name (mark)));
+
+  gtk_text_mark_set_visible (mark, FALSE);
+  gtk_text_buffer_delete_mark (buf1, mark);
+  g_assert (!gtk_text_mark_get_visible (mark));
+  g_assert (gtk_text_buffer_get_mark (buf1, "blah") == NULL);
+  g_assert (gtk_text_mark_get_buffer (mark) == NULL);
+  g_assert (gtk_text_mark_get_deleted (mark));
+
+  gtk_text_buffer_get_start_iter (buf2, &iter);
+  gtk_text_buffer_add_mark (buf2, mark, &iter);
+  g_assert (gtk_text_mark_get_buffer (mark) == buf2);
+  g_assert (!gtk_text_mark_get_deleted (mark));
+  g_assert (gtk_text_buffer_get_mark (buf2, "blah") == mark);
+  g_assert (!strcmp ("blah", gtk_text_mark_get_name (mark)));
+
+  g_object_unref (mark);
+  g_object_unref (buf1);
+  g_object_unref (buf2);
+}
+
+static void
+test_utf8 (void)
+{
+  gunichar ch;
+
+  /* Check UTF8 unknown char thing */
+  g_assert (GTK_TEXT_UNKNOWN_CHAR_UTF8_LEN == 3);
+  g_assert (g_utf8_strlen (gtk_text_unknown_char_utf8_gtk_tests_only (), 3) == 1);
+  ch = g_utf8_get_char (gtk_text_unknown_char_utf8_gtk_tests_only ());
+  g_assert (ch == GTK_TEXT_UNKNOWN_CHAR);
+}
+
+static void
+test_empty_buffer (void)
+{
+  GtkTextBuffer *buffer;
+  int n;
+  GtkTextIter start;
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  /* Check that buffer starts with one empty line and zero chars */
+  n = gtk_text_buffer_get_line_count (buffer);
+  if (n != 1)
+    g_error ("%d lines, expected 1", n);
+
+  n = gtk_text_buffer_get_char_count (buffer);
+  if (n != 0)
+    g_error ("%d chars, expected 0", n);
+
+  /* empty first line contains 0 chars */
+  gtk_text_buffer_get_start_iter (buffer, &start);
+  n = gtk_text_iter_get_chars_in_line (&start);
+  if (n != 0)
+    g_error ("%d chars in first line, expected 0", n);
+  n = gtk_text_iter_get_bytes_in_line (&start);
+  if (n != 0)
+    g_error ("%d bytes in first line, expected 0", n);
+  
+  /* Run gruesome alien test suite on buffer */
+  run_tests (buffer);
+
+  g_object_unref (buffer);
+}
+
+static void
+test_get_set(void)
+{
+  GtkTextBuffer *buffer;
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  check_get_set_text (buffer, "Hello");
+  check_get_set_text (buffer, "Hello\n");
+  check_get_set_text (buffer, "Hello\r\n");
+  check_get_set_text (buffer, "Hello\r");
+  check_get_set_text (buffer, "Hello\nBar\nFoo");
+  check_get_set_text (buffer, "Hello\nBar\nFoo\n");
+
+  g_object_unref (buffer);
+}
+
+static void
+test_fill_empty (void)
+{
+  GtkTextBuffer *buffer;
+  int n;
+  GtkTextIter start, end;
+  
+  buffer = gtk_text_buffer_new (NULL);
+
+  /* Put stuff in the buffer */
+  fill_buffer (buffer);
+
+  /* Subject stuff-bloated buffer to further torment */
+  run_tests (buffer);
+
+  /* Delete all stuff from the buffer */
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+  gtk_text_buffer_delete (buffer, &start, &end);
+
+  /* Check buffer for emptiness (note that a single
+     empty line always remains in the buffer) */
+  n = gtk_text_buffer_get_line_count (buffer);
+  if (n != 1)
+    g_error ("%d lines, expected 1", n);
+
+  n = gtk_text_buffer_get_char_count (buffer);
+  if (n != 0)
+    g_error ("%d chars, expected 0", n);
+
+  run_tests (buffer);
+
+  g_object_unref (buffer);
+}
+
+static void
+test_tag (void)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter start, end;
+  
+  buffer = gtk_text_buffer_new (NULL);
+
+  fill_buffer (buffer);
+
+  gtk_text_buffer_set_text (buffer, "adcdef", -1);
+  gtk_text_buffer_get_iter_at_offset (buffer, &start, 1);
+  gtk_text_buffer_get_iter_at_offset (buffer, &end, 3);
+  gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &start, &end);
+  
+  run_tests (buffer);
+  
+  g_object_unref (buffer);
+}
+
+int
+main (int argc, char** argv)
+{
+  /* First, we turn on btree debugging. */
+  gtk_set_debug_flags (gtk_get_debug_flags () | GTK_DEBUG_TEXT);
+
+  gtk_test_init (&argc, &argv);
+
+  g_test_add_func ("/TextBuffer/UTF8 unknown char", test_utf8);
+  g_test_add_func ("/TextBuffer/Line separator", test_line_separator);
+  g_test_add_func ("/TextBuffer/Backspace", test_backspace);
+  g_test_add_func ("/TextBuffer/Logical motion", test_logical_motion);
+  g_test_add_func ("/TextBuffer/Marks", test_marks);
+  g_test_add_func ("/TextBuffer/Empty buffer", test_empty_buffer);
+  g_test_add_func ("/TextBuffer/Get and Set", test_get_set);
+  g_test_add_func ("/TextBuffer/Fill and Empty", test_fill_empty);
+  g_test_add_func ("/TextBuffer/Tag", test_tag);
+  
+  return g_test_run();
+}
diff --git a/testsuite/gtk/textiter.c b/testsuite/gtk/textiter.c
new file mode 100644 (file)
index 0000000..bee33de
--- /dev/null
@@ -0,0 +1,269 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+static void
+test_empty_search ()
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter it, s, e;
+  gboolean res;
+
+  buffer = gtk_text_buffer_new (NULL);
+  gtk_text_buffer_set_text (buffer, "This is some foo text", -1);
+
+  /* search from start forward */
+  gtk_text_buffer_get_start_iter (buffer, &it);
+  res = gtk_text_iter_forward_search (&it, "", 0, &s, &e, NULL);
+  g_assert (res);
+  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e));
+  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 1);
+
+  /* search from end backward */
+  gtk_text_buffer_get_end_iter (buffer, &it);
+  res = gtk_text_iter_backward_search (&it, "", 0, &s, &e, NULL);
+  g_assert (res);
+  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e));
+  g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 20);
+}
+
+static void
+check_found_forward (const gchar *haystack,
+                     const gchar *needle,
+                     GtkTextSearchFlags flags,
+                     int expected_start,
+                     int expected_end,
+                     const gchar *expected_string)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter i, s, e;
+  gboolean res;
+  gchar *text;
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  gtk_text_buffer_set_text (buffer, haystack, -1);
+
+  /* TODO: add test with limit before, after and in the middle
+     of expected start and end */
+
+  /* search from start forward */
+  gtk_text_buffer_get_start_iter (buffer, &i);
+  res = gtk_text_iter_forward_search (&i, needle, flags, &s, &e, NULL);
+  g_assert (res);
+  g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s));
+  g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e));
+  text = gtk_text_iter_get_text (&s, &e);
+  g_assert_cmpstr (expected_string, ==, text);
+  g_free (text);
+
+  g_object_unref (buffer);
+}
+
+static void
+check_found_backward (const gchar *haystack,
+                      const gchar *needle,
+                      GtkTextSearchFlags flags,
+                      int expected_start,
+                      int expected_end,
+                      const gchar *expected_string)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter i, s, e;
+  gboolean res;
+  gchar *text;
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  gtk_text_buffer_set_text (buffer, haystack, -1);
+
+  /* search from end backward */
+  gtk_text_buffer_get_end_iter (buffer, &i);
+  res = gtk_text_iter_backward_search (&i, needle, flags, &s, &e, NULL);
+  g_assert (res);
+  g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s));
+  g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e));
+  text = gtk_text_iter_get_text (&s, &e);
+  g_assert_cmpstr (expected_string, ==, text);
+  g_free (text);
+
+  g_object_unref (buffer);
+}
+
+static void
+check_not_found (const gchar *haystack,
+                 const gchar *needle,
+                 GtkTextSearchFlags flags)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter i, s, e;
+  gboolean res;
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  gtk_text_buffer_set_text (buffer, haystack, -1);
+
+  /* search from start forward */
+  gtk_text_buffer_get_start_iter (buffer, &i);
+  res = gtk_text_iter_forward_search (&i, needle, flags, &s, &e, NULL);
+  g_assert (res == FALSE);
+
+  /* search from end backward */
+  gtk_text_buffer_get_end_iter (buffer, &i);
+  res = gtk_text_iter_backward_search (&i, needle, flags, &s, &e, NULL);
+  g_assert (res == FALSE);
+
+  g_object_unref (buffer);
+}
+
+static void
+test_full_buffer (void)
+{
+  check_found_forward ("foo", "foo", 0, 0, 3, "foo");
+  check_found_backward ("foo", "foo", 0, 0, 3, "foo");
+  check_found_forward ("foo", "foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
+  check_found_backward ("foo", "foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
+  check_found_forward ("foo", "Foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
+  check_found_backward ("foo", "Foo", GTK_TEXT_SEARCH_CASE_INSENSITIVE, 0, 3, "foo");
+}
+
+static void
+test_search (void)
+{
+  /* simple match */
+  check_found_forward ("This is some foo text", "foo", 0, 13, 16, "foo");
+  check_found_backward ("This is some foo text", "foo", 0, 13, 16, "foo");
+  check_not_found ("This is some foo text", "Foo", 0);
+
+  /* different matches for forward and backward */
+  check_found_forward ("This is some foo foo text", "foo", 0, 13, 16, "foo");
+  check_found_backward ("This is some foo foo text", "foo", 0, 17, 20, "foo");
+
+  /* new lines in the haystack */
+  check_found_forward ("This is some\nfoo text", "foo", 0, 13, 16, "foo");
+  check_found_backward ("This is some\nfoo text", "foo", 0, 13, 16, "foo");
+  check_found_forward ("This is some foo\nfoo text", "foo", 0, 13, 16, "foo");
+  check_found_backward ("This is some foo\nfoo text", "foo", 0, 17, 20, "foo");
+  check_not_found ("This is some\nfoo text", "Foo", 0);
+
+  /* end of buffer */
+  check_found_forward ("This is some\ntext foo", "foo", 0, 18, 21, "foo");
+  check_found_backward ("This is some\ntext foo", "foo", 0, 18, 21, "foo");
+  check_not_found ("This is some\ntext foo", "Foo", 0);
+
+  /* multiple lines in the needle */
+  check_found_forward ("This is some foo\nfoo text", "foo\nfoo", 0, 13, 20, "foo\nfoo");
+  check_found_backward ("This is some foo\nfoo text", "foo\nfoo", 0, 13, 20, "foo\nfoo");
+  check_not_found ("This is some foo\nfoo text", "Foo\nfoo", 0);
+}
+
+static void
+test_search_caseless (void)
+{
+  GtkTextSearchFlags flags;
+
+  flags = GTK_TEXT_SEARCH_CASE_INSENSITIVE;
+
+  /* simple match */
+  check_found_forward ("This is some foo text", "foo", flags, 13, 16, "foo");
+  check_found_forward ("This is some foo text", "Foo", flags, 13, 16, "foo");
+  check_found_forward ("This is some Foo text", "foo", flags, 13, 16, "Foo");
+  check_found_backward ("This is some foo text", "foo", flags, 13, 16, "foo");
+  check_found_backward ("This is some foo text", "Foo", flags, 13, 16, "foo");
+  check_found_backward ("This is some Foo text", "foo", flags, 13, 16, "Foo");
+
+  /* check also that different composition of utf8 characters
+     (e.g. accented letters) match */
+
+  /* different matches for forward and backward */
+  check_found_forward ("This is some foo foo text", "foo", flags, 13, 16, "foo");
+  check_found_forward ("This is some foo foo text", "Foo", flags, 13, 16, "foo");
+  check_found_forward ("This is some Foo foo text", "foo", flags, 13, 16, "Foo");
+  check_found_forward ("This is some \303\200 \303\240 text", "\303\240", flags, 13, 14, "\303\200");
+  check_found_forward ("This is some \303\200 \303\240 text", "\303\200", flags, 13, 14, "\303\200");
+  check_found_forward ("This is some \303\200 \303\240 text", "a\314\200", flags, 13, 14, "\303\200");
+  check_found_backward ("This is some foo foo text", "foo", flags, 17, 20, "foo");
+  check_found_backward ("This is some foo foo text", "Foo", flags, 17, 20, "foo");
+  check_found_backward ("This is some foo Foo text", "foo", flags, 17, 20, "Foo");
+  check_found_backward ("This is some \303\200 \303\240 text", "\303\240", flags, 15, 16, "\303\240");
+  check_found_backward ("This is some \303\200 \303\240 text", "\303\200", flags, 15, 16, "\303\240");
+  check_found_backward ("This is some \303\200 \303\240 text", "a\314\200", flags, 15, 16, "\303\240");
+
+  /* new lines in the haystack */
+  check_found_forward ("This is some\nfoo text", "foo", flags, 13, 16, "foo");
+  check_found_forward ("This is some\nfoo text", "Foo", flags, 13, 16, "foo");
+  check_found_forward ("This is some\nFoo text", "foo", flags, 13, 16, "Foo");
+  check_found_forward ("This is some\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
+  check_found_forward ("This is some\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
+  check_found_backward ("This is some\nfoo text", "foo", flags, 13, 16, "foo");
+  check_found_backward ("This is some\nfoo text", "Foo", flags, 13, 16, "foo");
+  check_found_backward ("This is some\nFoo text", "foo", flags, 13, 16, "Foo");
+  check_found_backward ("This is some\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
+  check_found_backward ("This is some\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
+  check_found_forward ("This is some foo\nfoo text", "foo", flags, 13, 16, "foo");
+  check_found_forward ("This is some foo\nfoo text", "Foo", flags, 13, 16, "foo");
+  check_found_forward ("This is some Foo\nfoo text", "foo", flags, 13, 16, "Foo");
+  check_found_forward ("This is some \303\200\n\303\200 text", "\303\240", flags, 13, 14, "\303\200");
+  check_found_forward ("This is some \303\200\n\303\200 text", "a\314\200", flags, 13, 14, "\303\200");
+  check_found_backward ("This is some foo\nfoo text", "foo", flags, 17, 20, "foo");
+  check_found_backward ("This is some foo\nfoo text", "Foo", flags, 17, 20, "foo");
+  check_found_backward ("This is some foo\nFoo text", "foo", flags, 17, 20, "Foo");
+  check_found_backward ("This is some \303\200\n\303\200 text", "\303\240", flags, 15, 16, "\303\200");
+  check_found_backward ("This is some \303\200\n\303\200 text", "a\314\200", flags, 15, 16, "\303\200");
+
+  /* end of buffer */
+  check_found_forward ("This is some\ntext foo", "foo", flags, 18, 21, "foo");
+  check_found_forward ("This is some\ntext foo", "Foo", flags, 18, 21, "foo");
+  check_found_forward ("This is some\ntext Foo", "foo", flags, 18, 21, "Foo");
+  check_found_forward ("This is some\ntext \303\200", "\303\240", flags, 18, 19, "\303\200");
+  check_found_forward ("This is some\ntext \303\200", "a\314\200", flags, 18, 19, "\303\200");
+  check_found_backward ("This is some\ntext foo", "foo", flags, 18, 21, "foo");
+  check_found_backward ("This is some\ntext foo", "Foo", flags, 18, 21, "foo");
+  check_found_backward ("This is some\ntext Foo", "foo", flags, 18, 21, "Foo");
+  check_found_backward ("This is some\ntext \303\200", "\303\240", flags, 18, 19, "\303\200");
+  check_found_backward ("This is some\ntext \303\200", "a\314\200", flags, 18, 19, "\303\200");
+
+  /* multiple lines in the needle */
+  check_found_forward ("This is some foo\nfoo text", "foo\nfoo", flags, 13, 20, "foo\nfoo");
+  check_found_forward ("This is some foo\nfoo text", "Foo\nFoo", flags, 13, 20, "foo\nfoo");
+  check_found_forward ("This is some Foo\nFoo text", "foo\nfoo", flags, 13, 20, "Foo\nFoo");
+  check_found_forward ("This is some \303\200\n\303\200 text", "\303\240\n\303\240", flags, 13, 16, "\303\200\n\303\200");
+  check_found_forward ("This is some \303\200\n\303\200 text", "a\314\200\na\314\200", flags, 13, 16, "\303\200\n\303\200");
+  check_found_backward ("This is some foo\nfoo text", "foo\nfoo", flags, 13, 20, "foo\nfoo");
+  check_found_backward ("This is some foo\nfoo text", "Foo\nFoo", flags, 13, 20, "foo\nfoo");
+  check_found_backward ("This is some Foo\nFoo text", "foo\nfoo", flags, 13, 20, "Foo\nFoo");
+  check_found_backward ("This is some \303\200\n\303\200 text", "\303\240\n\303\240", flags, 13, 16, "\303\200\n\303\200");
+  check_found_backward ("This is some \303\200\n\303\200 text", "a\314\200\na\314\200", flags, 13, 16, "\303\200\n\303\200");
+}
+
+int
+main (int argc, char** argv)
+{
+  gtk_test_init (&argc, &argv);
+
+  g_test_add_func ("/TextIter/Search Empty", test_empty_search);
+  g_test_add_func ("/TextIter/Search Full Buffer", test_full_buffer);
+  g_test_add_func ("/TextIter/Search", test_search);
+  g_test_add_func ("/TextIter/Search Caseless", test_search_caseless);
+
+  return g_test_run();
+}
diff --git a/testsuite/gtk/treemodel.c b/testsuite/gtk/treemodel.c
new file mode 100644 (file)
index 0000000..13eeb4f
--- /dev/null
@@ -0,0 +1,345 @@
+/* Main wrapper for TreeModel test suite.
+ * Copyright (C) 2011  Kristian Rietveld  <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+#include "treemodel.h"
+
+int
+main (int    argc,
+      char **argv)
+{
+  gtk_test_init (&argc, &argv, NULL);
+
+  g_test_bug_base ("http://bugzilla.gnome.org/");
+
+  register_list_store_tests ();
+  register_tree_store_tests ();
+  register_model_ref_count_tests ();
+  register_sort_model_tests ();
+  register_filter_model_tests ();
+
+  return g_test_run ();
+}
+
+/*
+ * Signal monitor
+ */
+
+static const char *
+signal_name_to_string (SignalName signal)
+{
+  switch (signal)
+    {
+      case ROW_INSERTED:
+          return "row-inserted";
+
+      case ROW_DELETED:
+          return "row-deleted";
+
+      case ROW_CHANGED:
+          return "row-changed";
+
+      case ROW_HAS_CHILD_TOGGLED:
+          return "row-has-child-toggled";
+
+      case ROWS_REORDERED:
+          return "rows-reordered";
+
+      default:
+          /* Fall through */
+          break;
+    }
+
+  return "(unknown)";
+}
+
+typedef struct
+{
+  SignalName signal;
+  GtkTreePath *path;
+
+  /* For rows-reordered */
+  int *new_order;
+  int len;
+}
+Signal;
+
+
+static Signal *
+signal_new (SignalName signal, GtkTreePath *path)
+{
+  Signal *s;
+
+  s = g_new0 (Signal, 1);
+  s->signal = signal;
+  s->path = gtk_tree_path_copy (path);
+  s->new_order = NULL;
+
+  return s;
+}
+
+static Signal *
+signal_new_with_order (SignalName signal, GtkTreePath *path,
+                       int *new_order, int len)
+{
+  Signal *s = signal_new (signal, path);
+
+  s->new_order = new_order;
+  s->len = len;
+
+  return s;
+}
+
+static void
+signal_free (Signal *s)
+{
+  if (s->path)
+    gtk_tree_path_free (s->path);
+
+  g_free (s);
+}
+
+
+struct _SignalMonitor
+{
+  GQueue *queue;
+  GtkTreeModel *client;
+  gulong signal_ids[LAST_SIGNAL];
+};
+
+
+static void
+signal_monitor_generic_handler (SignalMonitor *m,
+                                SignalName     signal,
+                                GtkTreeModel  *model,
+                                GtkTreeIter   *iter,
+                                GtkTreePath   *path,
+                                int           *new_order)
+{
+  Signal *s;
+
+  if (g_queue_is_empty (m->queue))
+    {
+      gchar *path_str;
+
+      path_str = gtk_tree_path_to_string (path);
+      g_error ("Signal queue empty, got signal %s path %s\n",
+               signal_name_to_string (signal), path_str);
+      g_free (path_str);
+
+      g_assert_not_reached ();
+    }
+
+  if (m->client != model)
+    {
+      g_error ("Model mismatch; expected %p, got %p\n",
+               m->client, model);
+      g_assert_not_reached ();
+    }
+
+  s = g_queue_peek_tail (m->queue);
+
+#if 0
+  /* For debugging: output signals that are coming in.  Leaks memory. */
+  g_print ("signal=%s path=%s\n", signal_name_to_string (signal),
+           gtk_tree_path_to_string (path));
+#endif
+
+  if (s->signal != signal ||
+      (gtk_tree_path_get_depth (s->path) == 0 &&
+       gtk_tree_path_get_depth (path) != 0) ||
+      (gtk_tree_path_get_depth (s->path) != 0 &&
+       gtk_tree_path_compare (s->path, path) != 0))
+    {
+      gchar *path_str, *s_path_str;
+
+      s_path_str = gtk_tree_path_to_string (s->path);
+      path_str = gtk_tree_path_to_string (path);
+
+      g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n",
+               signal_name_to_string (s->signal), s_path_str,
+               signal_name_to_string (signal), path_str);
+
+      g_free (s_path_str);
+      g_free (path_str);
+
+      g_assert_not_reached ();
+    }
+
+  if (signal == ROWS_REORDERED && s->new_order != NULL)
+    {
+      int i, len;
+
+      g_assert (new_order != NULL);
+
+      len = gtk_tree_model_iter_n_children (model, iter);
+      g_assert (s->len == len);
+
+      for (i = 0; i < len; i++)
+        g_assert (s->new_order[i] == new_order[i]);
+    }
+
+  s = g_queue_pop_tail (m->queue);
+
+  signal_free (s);
+}
+
+static void
+signal_monitor_row_inserted (GtkTreeModel *model,
+                             GtkTreePath  *path,
+                             GtkTreeIter  *iter,
+                             gpointer      data)
+{
+  signal_monitor_generic_handler (data, ROW_INSERTED,
+                                  model, iter, path, NULL);
+}
+
+static void
+signal_monitor_row_deleted (GtkTreeModel *model,
+                            GtkTreePath  *path,
+                            gpointer      data)
+{
+  signal_monitor_generic_handler (data, ROW_DELETED,
+                                  model, NULL, path, NULL);
+}
+
+static void
+signal_monitor_row_changed (GtkTreeModel *model,
+                            GtkTreePath  *path,
+                            GtkTreeIter  *iter,
+                            gpointer      data)
+{
+  signal_monitor_generic_handler (data, ROW_CHANGED,
+                                  model, iter, path, NULL);
+}
+
+static void
+signal_monitor_row_has_child_toggled (GtkTreeModel *model,
+                                      GtkTreePath  *path,
+                                      GtkTreeIter  *iter,
+                                      gpointer      data)
+{
+  signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
+                                  model, iter, path, NULL);
+}
+
+static void
+signal_monitor_rows_reordered (GtkTreeModel *model,
+                               GtkTreePath  *path,
+                               GtkTreeIter  *iter,
+                               gint         *new_order,
+                               gpointer      data)
+{
+  signal_monitor_generic_handler (data, ROWS_REORDERED,
+                                  model, iter, path, new_order);
+}
+
+SignalMonitor *
+signal_monitor_new (GtkTreeModel *client)
+{
+  SignalMonitor *m;
+
+  m = g_new0 (SignalMonitor, 1);
+  m->client = g_object_ref (client);
+  m->queue = g_queue_new ();
+
+  m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
+                                                  "row-inserted",
+                                                  G_CALLBACK (signal_monitor_row_inserted),
+                                                  m);
+  m->signal_ids[ROW_DELETED] = g_signal_connect (client,
+                                                 "row-deleted",
+                                                 G_CALLBACK (signal_monitor_row_deleted),
+                                                 m);
+  m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
+                                                 "row-changed",
+                                                 G_CALLBACK (signal_monitor_row_changed),
+                                                 m);
+  m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
+                                                           "row-has-child-toggled",
+                                                           G_CALLBACK (signal_monitor_row_has_child_toggled),
+                                                           m);
+  m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
+                                                    "rows-reordered",
+                                                    G_CALLBACK (signal_monitor_rows_reordered),
+                                                    m);
+
+  return m;
+}
+
+void
+signal_monitor_free (SignalMonitor *m)
+{
+  int i;
+
+  for (i = 0; i < LAST_SIGNAL; i++)
+    g_signal_handler_disconnect (m->client, m->signal_ids[i]);
+
+  g_object_unref (m->client);
+
+  if (m->queue)
+    g_queue_free (m->queue);
+
+  g_free (m);
+}
+
+void
+signal_monitor_assert_is_empty (SignalMonitor *m)
+{
+  g_assert (g_queue_is_empty (m->queue));
+}
+
+void
+signal_monitor_append_signal_path (SignalMonitor *m,
+                                   SignalName     signal,
+                                   GtkTreePath   *path)
+{
+  Signal *s;
+
+  s = signal_new (signal, path);
+  g_queue_push_head (m->queue, s);
+}
+
+void
+signal_monitor_append_signal_reordered (SignalMonitor *m,
+                                        SignalName     signal,
+                                        GtkTreePath   *path,
+                                        int           *new_order,
+                                        int            len)
+{
+  Signal *s;
+
+  s = signal_new_with_order (signal, path, new_order, len);
+  g_queue_push_head (m->queue, s);
+}
+
+void
+signal_monitor_append_signal (SignalMonitor *m,
+                              SignalName     signal,
+                              const gchar   *path_string)
+{
+  Signal *s;
+  GtkTreePath *path;
+
+  path = gtk_tree_path_new_from_string (path_string);
+
+  s = signal_new (signal, path);
+  g_queue_push_head (m->queue, s);
+
+  gtk_tree_path_free (path);
+}
diff --git a/testsuite/gtk/treemodel.h b/testsuite/gtk/treemodel.h
new file mode 100644 (file)
index 0000000..3723057
--- /dev/null
@@ -0,0 +1,58 @@
+/* Main wrapper for TreeModel test suite.
+ * Copyright (C) 2011  Kristian Rietveld  <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+void register_list_store_tests ();
+void register_tree_store_tests ();
+void register_sort_model_tests ();
+void register_filter_model_tests ();
+void register_model_ref_count_tests ();
+
+/*
+ * Signal monitor
+ */
+typedef struct _SignalMonitor           SignalMonitor;
+typedef enum _SignalName                SignalName;
+
+enum _SignalName
+{
+  ROW_INSERTED,
+  ROW_DELETED,
+  ROW_CHANGED,
+  ROW_HAS_CHILD_TOGGLED,
+  ROWS_REORDERED,
+  LAST_SIGNAL
+};
+
+
+SignalMonitor *signal_monitor_new                     (GtkTreeModel  *client);
+void           signal_monitor_free                    (SignalMonitor *m);
+
+void           signal_monitor_assert_is_empty         (SignalMonitor *m);
+
+void           signal_monitor_append_signal_reordered (SignalMonitor *m,
+                                                       SignalName     signal,
+                                                       GtkTreePath   *path,
+                                                       int           *new_order,
+                                                       int            len);
+void           signal_monitor_append_signal_path      (SignalMonitor *m,
+                                                       SignalName     signal,
+                                                       GtkTreePath   *path);
+void           signal_monitor_append_signal           (SignalMonitor *m,
+                                                       SignalName     signal,
+                                                       const gchar   *path_string);
diff --git a/testsuite/gtk/treepath.c b/testsuite/gtk/treepath.c
new file mode 100644 (file)
index 0000000..c014de2
--- /dev/null
@@ -0,0 +1,181 @@
+/* GtkTrePath tests.
+ *
+ * Copyright (C) 2011, Red Hat, Inc.
+ * Authors: Matthias Clasen <mclasen@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+static void
+test_append (void)
+{
+  GtkTreePath *p;
+  gint i;
+  gint *indices;
+
+  p = gtk_tree_path_new ();
+  for (i = 0; i < 100; i++)
+    {
+      g_assert_cmpint (gtk_tree_path_get_depth (p), ==, i);
+      gtk_tree_path_append_index (p, i);
+    }
+
+  indices = gtk_tree_path_get_indices (p);
+  for (i = 0; i < 100; i++)
+    g_assert_cmpint (indices[i], ==, i);
+
+  gtk_tree_path_free (p);
+}
+
+static void
+test_prepend (void)
+{
+  GtkTreePath *p;
+  gint i;
+  gint *indices;
+
+  p = gtk_tree_path_new ();
+  for (i = 0; i < 100; i++)
+    {
+      g_assert_cmpint (gtk_tree_path_get_depth (p), ==, i);
+      gtk_tree_path_prepend_index (p, i);
+    }
+
+  indices = gtk_tree_path_get_indices (p);
+  for (i = 0; i < 100; i++)
+    g_assert_cmpint (indices[i], ==, 99 - i);
+
+  gtk_tree_path_free (p);
+}
+
+static void
+test_to_string (void)
+{
+  const gchar *str = "0:1:2:3:4:5:6:7:8:9:10";
+  GtkTreePath *p;
+  gint *indices;
+  gchar *s;
+  gint i;
+
+  p = gtk_tree_path_new_from_string (str);
+  indices = gtk_tree_path_get_indices (p);
+  for (i = 0; i < 10; i++)
+    g_assert_cmpint (indices[i], ==, i);
+  s = gtk_tree_path_to_string (p);
+  g_assert_cmpstr (s, ==, str);
+
+  gtk_tree_path_free (p);
+  g_free (s);
+}
+
+static void
+test_from_indices (void)
+{
+  GtkTreePath *p;
+  gint *indices;
+  gint i;
+
+  p = gtk_tree_path_new_from_indices (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1);
+  g_assert_cmpint (gtk_tree_path_get_depth (p), ==, 10);
+  indices = gtk_tree_path_get_indices (p);
+  for (i = 0; i < 10; i++)
+    g_assert_cmpint (indices[i], ==, i);
+  gtk_tree_path_free (p);
+}
+
+static void
+test_first (void)
+{
+  GtkTreePath *p;
+  p = gtk_tree_path_new_first ();
+  g_assert_cmpint (gtk_tree_path_get_depth (p), ==, 1);
+  g_assert_cmpint (gtk_tree_path_get_indices (p)[0], ==, 0);
+  gtk_tree_path_free (p);
+}
+
+static void
+test_navigation (void)
+{
+  GtkTreePath *p;
+  GtkTreePath *q;
+  gint *pi;
+  gint *qi;
+  gint i;
+  gboolean res;
+
+  p = gtk_tree_path_new_from_indices (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1);
+  q = gtk_tree_path_copy (p);
+  g_assert (gtk_tree_path_compare (p, q) == 0);
+  gtk_tree_path_next (q);
+  pi = gtk_tree_path_get_indices (p);
+  qi = gtk_tree_path_get_indices (q);
+  for (i = 0; i < 9; i++)
+    g_assert_cmpint (pi[i], ==, qi[i]);
+  g_assert_cmpint (qi[9], ==, pi[9] + 1);
+
+  g_assert (!gtk_tree_path_is_ancestor (p, q));
+  g_assert (!gtk_tree_path_is_ancestor (q, p));
+  g_assert (!gtk_tree_path_is_descendant (p, q));
+  g_assert (!gtk_tree_path_is_descendant (q, p));
+
+  res = gtk_tree_path_prev (q);
+  g_assert (res);
+  g_assert (gtk_tree_path_compare (p, q) == 0);
+
+  g_assert (!gtk_tree_path_is_ancestor (p, q));
+  g_assert (!gtk_tree_path_is_ancestor (q, p));
+  g_assert (!gtk_tree_path_is_descendant (p, q));
+  g_assert (!gtk_tree_path_is_descendant (q, p));
+
+  gtk_tree_path_down (q);
+
+  g_assert (gtk_tree_path_compare (p, q) < 0);
+
+  g_assert (gtk_tree_path_is_ancestor (p, q));
+  g_assert (!gtk_tree_path_is_ancestor (q, p));
+  g_assert (!gtk_tree_path_is_descendant (p, q));
+  g_assert (gtk_tree_path_is_descendant (q, p));
+
+  res = gtk_tree_path_prev (q);
+  g_assert (!res);
+
+  res = gtk_tree_path_up (q);
+  g_assert (res);
+  g_assert (gtk_tree_path_compare (p, q) == 0);
+
+  g_assert_cmpint (gtk_tree_path_get_depth (q), ==, 10);
+  res = gtk_tree_path_up (q);
+  g_assert (res);
+  g_assert_cmpint (gtk_tree_path_get_depth (q), ==, 9);
+
+  gtk_tree_path_free (p);
+  gtk_tree_path_free (q);
+}
+
+int
+main (int argc, char *argv[])
+{
+  gtk_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/tree-path/append", test_append);
+  g_test_add_func ("/tree-path/prepend", test_prepend);
+  g_test_add_func ("/tree-path/to-string", test_to_string);
+  g_test_add_func ("/tree-path/from-indices", test_from_indices);
+  g_test_add_func ("/tree-path/first", test_first);
+  g_test_add_func ("/tree-path/navigation", test_navigation);
+
+  return g_test_run ();
+}
diff --git a/testsuite/gtk/treestore.c b/testsuite/gtk/treestore.c
new file mode 100644 (file)
index 0000000..d19297f
--- /dev/null
@@ -0,0 +1,1178 @@
+/* Extensive GtkTreeStore tests.
+ * Copyright (C) 2007  Imendio AB
+ * Authors: Kristian Rietveld  <kris@imendio.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* To do:
+ *  - All the to do items from liststore.c, plus:
+ *  - Finish up the insertion tests; things aren't as nicely refactored
+ *    here as in GtkListStore, so we need to check for corner cases on
+ *    all insertion functions separately.
+ *  - We only test in the root level, we also need all tests "duplicated"
+ *    for child levels.
+ *  - And we also need tests for creating these child levels, etc.
+ */
+
+#include "treemodel.h"
+
+#include <gtk/gtk.h>
+
+static inline gboolean
+iters_equal (GtkTreeIter *a,
+            GtkTreeIter *b)
+{
+  if (a->stamp != b->stamp)
+    return FALSE;
+
+  if (a->user_data != b->user_data)
+    return FALSE;
+
+  /* user_data2 and user_data3 are not used in GtkTreeStore */
+
+  return TRUE;
+}
+
+static gboolean
+iter_position (GtkTreeStore *store,
+              GtkTreeIter  *iter,
+              int           n)
+{
+  gboolean ret = TRUE;
+  GtkTreePath *path;
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
+  if (!path)
+    return FALSE;
+
+  if (gtk_tree_path_get_indices (path)[0] != n)
+    ret = FALSE;
+
+  gtk_tree_path_free (path);
+
+  return ret;
+}
+
+/*
+ * Fixture
+ */
+typedef struct
+{
+  GtkTreeIter iter[5];
+  GtkTreeStore *store;
+} TreeStore;
+
+static void
+tree_store_setup (TreeStore     *fixture,
+                 gconstpointer  test_data)
+{
+  int i;
+
+  fixture->store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  for (i = 0; i < 5; i++)
+    {
+      gtk_tree_store_insert (fixture->store, &fixture->iter[i], NULL, i);
+      gtk_tree_store_set (fixture->store, &fixture->iter[i], 0, i, -1);
+    }
+}
+
+static void
+tree_store_teardown (TreeStore     *fixture,
+                    gconstpointer  test_data)
+{
+  g_object_unref (fixture->store);
+}
+
+/*
+ * The actual tests.
+ */
+
+static void
+check_model (TreeStore *fixture,
+            gint      *new_order,
+            gint       skip)
+{
+  int i;
+  GtkTreePath *path;
+
+  path = gtk_tree_path_new ();
+  gtk_tree_path_down (path);
+
+  /* Check validity of the model and validity of the iters-persistent
+   * claim.
+   */
+  for (i = 0; i < 5; i++)
+    {
+      GtkTreeIter iter;
+
+      if (i == skip)
+       continue;
+
+      /* The saved iterator at new_order[i] should match the iterator
+       * at i.
+       */
+
+      gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+                              &iter, path);
+
+      g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter));
+      g_assert (iters_equal (&iter, &fixture->iter[new_order[i]]));
+
+      gtk_tree_path_next (path);
+    }
+
+  gtk_tree_path_free (path);
+}
+
+/* insertion */
+static void
+tree_store_test_insert_high_values (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_insert (store, &iter, NULL, 1234);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  gtk_tree_store_insert (store, &iter2, NULL, 765);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+tree_store_test_append (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  gtk_tree_store_append (store, &iter2, NULL);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+tree_store_test_prepend (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_prepend (store, &iter, NULL);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  gtk_tree_store_prepend (store, &iter2, NULL);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+tree_store_test_insert_after (void)
+{
+  GtkTreeIter iter, iter2, iter3;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_append (store, &iter2, NULL);
+
+  gtk_tree_store_insert_after (store, &iter3, NULL, &iter);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter3));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 1));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 2));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 2));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+tree_store_test_insert_after_NULL (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_append (store, &iter, NULL);
+
+  /* move_after NULL is basically a prepend */
+  gtk_tree_store_insert_after (store, &iter2, NULL, NULL);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
+  g_assert (iters_equal (&iter2, &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+tree_store_test_insert_before (void)
+{
+  GtkTreeIter iter, iter2, iter3;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_append (store, &iter, NULL);
+  gtk_tree_store_append (store, &iter2, NULL);
+
+  gtk_tree_store_insert_before (store, &iter3, NULL, &iter2);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter3));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 1));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter_copy, 2));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter3, &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 2));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+static void
+tree_store_test_insert_before_NULL (void)
+{
+  GtkTreeIter iter, iter2;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  gtk_tree_store_append (store, &iter, NULL);
+
+  /* move_before NULL is basically an append */
+  gtk_tree_store_insert_before (store, &iter2, NULL, NULL);
+  g_assert (gtk_tree_store_iter_is_valid (store, &iter2));
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
+
+  /* Walk over the model */
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
+  g_object_unref (store);
+}
+
+/* setting values */
+static void
+tree_store_set_gvalue_to_transform (void)
+{
+  GtkTreeStore *store;
+  GtkTreeIter iter;
+  GValue value = G_VALUE_INIT;
+
+  /* https://bugzilla.gnome.org/show_bug.cgi?id=677649 */
+  store = gtk_tree_store_new (1, G_TYPE_LONG);
+  gtk_tree_store_append (store, &iter, NULL);
+
+  g_value_init (&value, G_TYPE_INT);
+  g_value_set_int (&value, 42);
+  gtk_tree_store_set_value (store, &iter, 0, &value);
+}
+
+/* removal */
+static void
+tree_store_test_remove_begin (TreeStore     *fixture,
+                             gconstpointer  user_data)
+{
+  int new_order[5] = { -1, 1, 2, 3, 4 };
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  /* Remove node at 0 */
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+  gtk_tree_path_free (path);
+
+  g_assert (gtk_tree_store_remove (fixture->store, &iter) == TRUE);
+  g_assert (!gtk_tree_store_iter_is_valid (fixture->store, &fixture->iter[0]));
+  g_assert (iters_equal (&iter, &fixture->iter[1]));
+
+  check_model (fixture, new_order, 0);
+}
+
+static void
+tree_store_test_remove_middle (TreeStore     *fixture,
+                              gconstpointer  user_data)
+{
+  int new_order[5] = { 0, 1, -1, 3, 4 };
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  /* Remove node at 2 */
+  path = gtk_tree_path_new_from_indices (2, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+  gtk_tree_path_free (path);
+
+  g_assert (gtk_tree_store_remove (fixture->store, &iter) == TRUE);
+  g_assert (!gtk_tree_store_iter_is_valid (fixture->store, &fixture->iter[2]));
+  g_assert (iters_equal (&iter, &fixture->iter[3]));
+
+  check_model (fixture, new_order, 2);
+}
+
+static void
+tree_store_test_remove_end (TreeStore     *fixture,
+                           gconstpointer  user_data)
+{
+  int new_order[5] = { 0, 1, 2, 3, -1 };
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  /* Remove node at 4 */
+  path = gtk_tree_path_new_from_indices (4, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+  gtk_tree_path_free (path);
+
+  g_assert (gtk_tree_store_remove (fixture->store, &iter) == FALSE);
+  g_assert (!gtk_tree_store_iter_is_valid (fixture->store, &fixture->iter[4]));
+
+  check_model (fixture, new_order, 4);
+}
+
+static void
+tree_store_test_clear (TreeStore     *fixture,
+                      gconstpointer  user_data)
+{
+  int i;
+
+  gtk_tree_store_clear (fixture->store);
+
+  g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL) == 0);
+
+  for (i = 0; i < 5; i++)
+    g_assert (!gtk_tree_store_iter_is_valid (fixture->store, &fixture->iter[i]));
+}
+
+/* reorder */
+
+static void
+tree_store_test_reorder (TreeStore     *fixture,
+                        gconstpointer  user_data)
+{
+  int new_order[5] = { 4, 1, 0, 2, 3 };
+
+  gtk_tree_store_reorder (fixture->store, NULL, new_order);
+  check_model (fixture, new_order, -1);
+}
+
+/* swapping */
+
+static void
+tree_store_test_swap_begin (TreeStore     *fixture,
+                           gconstpointer  user_data)
+{
+  /* We swap nodes 0 and 1 at the beginning */
+  int new_order[5] = { 1, 0, 2, 3, 4 };
+
+  GtkTreeIter iter_a;
+  GtkTreeIter iter_b;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
+
+  gtk_tree_store_swap (fixture->store, &iter_a, &iter_b);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_swap_middle_next (TreeStore     *fixture,
+                                 gconstpointer  user_data)
+{
+  /* We swap nodes 2 and 3 in the middle that are next to each other */
+  int new_order[5] = { 0, 1, 3, 2, 4 };
+
+  GtkTreeIter iter_a;
+  GtkTreeIter iter_b;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "2"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
+
+  gtk_tree_store_swap (fixture->store, &iter_a, &iter_b);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_swap_middle_apart (TreeStore     *fixture,
+                                  gconstpointer  user_data)
+{
+  /* We swap nodes 1 and 3 in the middle that are apart from each other */
+  int new_order[5] = { 0, 3, 2, 1, 4 };
+
+  GtkTreeIter iter_a;
+  GtkTreeIter iter_b;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "1"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
+
+  gtk_tree_store_swap (fixture->store, &iter_a, &iter_b);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_swap_end (TreeStore     *fixture,
+                         gconstpointer  user_data)
+{
+  /* We swap nodes 3 and 4 at the end */
+  int new_order[5] = { 0, 1, 2, 4, 3 };
+
+  GtkTreeIter iter_a;
+  GtkTreeIter iter_b;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "3"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
+
+  gtk_tree_store_swap (fixture->store, &iter_a, &iter_b);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_swap_single (void)
+{
+  GtkTreeIter iter;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  /* Check if swap on a store with a single node does not corrupt
+   * the store.
+   */
+
+  gtk_tree_store_append (store, &iter, NULL);
+  iter_copy = iter;
+
+  gtk_tree_store_swap (store, &iter, &iter);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  g_object_unref (store);
+}
+
+/* move after */
+
+static void
+tree_store_test_move_after_from_start (TreeStore     *fixture,
+                                      gconstpointer  user_data)
+{
+  /* We move node 0 after 2 */
+  int new_order[5] = { 1, 2, 0, 3, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
+
+  gtk_tree_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_after_next (TreeStore     *fixture,
+                                gconstpointer  user_data)
+{
+  /* We move node 2 after 3 */
+  int new_order[5] = { 0, 1, 3, 2, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
+
+  gtk_tree_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_after_apart (TreeStore     *fixture,
+                                 gconstpointer  user_data)
+{
+  /* We move node 1 after 3 */
+  int new_order[5] = { 0, 2, 3, 1, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
+
+  gtk_tree_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_after_end (TreeStore     *fixture,
+                               gconstpointer  user_data)
+{
+  /* We move node 2 after 4 */
+  int new_order[5] = { 0, 1, 3, 4, 2 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
+
+  gtk_tree_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_after_from_end (TreeStore     *fixture,
+                                    gconstpointer  user_data)
+{
+  /* We move node 4 after 1 */
+  int new_order[5] = { 0, 1, 4, 2, 3 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
+
+  gtk_tree_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_after_change_ends (TreeStore     *fixture,
+                                       gconstpointer  user_data)
+{
+  /* We move 0 after 4, this will cause both the head and tail ends to
+   * change.
+   */
+  int new_order[5] = { 1, 2, 3, 4, 0 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
+
+  gtk_tree_store_move_after (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_after_NULL (TreeStore     *fixture,
+                                gconstpointer  user_data)
+{
+  /* We move node 2, NULL should prepend */
+  int new_order[5] = { 2, 0, 1, 3, 4 };
+
+  GtkTreeIter iter;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+
+  gtk_tree_store_move_after (fixture->store, &iter, NULL);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_after_single (void)
+{
+  GtkTreeIter iter;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  /* Check if move-after on a store with a single node does not corrupt
+   * the store.
+   */
+
+  gtk_tree_store_append (store, &iter, NULL);
+  iter_copy = iter;
+
+  gtk_tree_store_move_after (store, &iter, NULL);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  gtk_tree_store_move_after (store, &iter, &iter);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  g_object_unref (store);
+}
+
+/* move before */
+
+static void
+tree_store_test_move_before_next (TreeStore     *fixture,
+                                 gconstpointer  user_data)
+{
+  /* We move node 3 before 2 */
+  int new_order[5] = { 0, 1, 3, 2, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
+
+  gtk_tree_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_before_apart (TreeStore     *fixture,
+                                  gconstpointer  user_data)
+{
+  /* We move node 1 before 3 */
+  int new_order[5] = { 0, 2, 1, 3, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
+
+  gtk_tree_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_before_to_start (TreeStore     *fixture,
+                                     gconstpointer  user_data)
+{
+  /* We move node 2 before 0 */
+  int new_order[5] = { 2, 0, 1, 3, 4 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
+
+  gtk_tree_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_before_from_end (TreeStore     *fixture,
+                                     gconstpointer  user_data)
+{
+  /* We move node 4 before 2 (replace end) */
+  int new_order[5] = { 0, 1, 4, 2, 3 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
+
+  gtk_tree_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_before_change_ends (TreeStore     *fixture,
+                                        gconstpointer  user_data)
+{
+  /* We move node 4 before 0 */
+  int new_order[5] = { 4, 0, 1, 2, 3 };
+
+  GtkTreeIter iter;
+  GtkTreeIter position;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
+
+  gtk_tree_store_move_before (fixture->store, &iter, &position);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_before_NULL (TreeStore     *fixture,
+                                 gconstpointer  user_data)
+{
+  /* We move node 2, NULL should append */
+  int new_order[5] = { 0, 1, 3, 4, 2 };
+
+  GtkTreeIter iter;
+
+  g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
+
+  gtk_tree_store_move_before (fixture->store, &iter, NULL);
+  check_model (fixture, new_order, -1);
+}
+
+static void
+tree_store_test_move_before_single (void)
+{
+  GtkTreeIter iter;
+  GtkTreeIter iter_copy;
+  GtkTreeStore *store;
+
+  store = gtk_tree_store_new (1, G_TYPE_INT);
+
+  /* Check if move-after on a store with a single node does not corrupt
+   * the store.
+   */
+
+  gtk_tree_store_append (store, &iter, NULL);
+  iter_copy = iter;
+
+  gtk_tree_store_move_before (store, &iter, NULL);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  gtk_tree_store_move_before (store, &iter, &iter);
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
+  g_assert (iters_equal (&iter, &iter_copy));
+
+  g_object_unref (store);
+}
+
+
+/* iter invalidation */
+
+static void
+tree_store_test_iter_previous_invalid (TreeStore     *fixture,
+                                       gconstpointer  user_data)
+{
+  GtkTreeIter iter;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
+                                          &iter) == FALSE);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
+  g_assert (iter.stamp == 0);
+}
+
+static void
+tree_store_test_iter_next_invalid (TreeStore     *fixture,
+                                   gconstpointer  user_data)
+{
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  path = gtk_tree_path_new_from_indices (4, -1);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
+  gtk_tree_path_free (path);
+
+  g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
+                                      &iter) == FALSE);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
+  g_assert (iter.stamp == 0);
+}
+
+static void
+tree_store_test_iter_children_invalid (TreeStore     *fixture,
+                                       gconstpointer  user_data)
+{
+  GtkTreeIter iter, child;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == TRUE);
+
+  g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
+                                          &child, &iter) == FALSE);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == FALSE);
+  g_assert (child.stamp == 0);
+}
+
+static void
+tree_store_test_iter_nth_child_invalid (TreeStore     *fixture,
+                                        gconstpointer  user_data)
+{
+  GtkTreeIter iter, child;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == TRUE);
+
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
+                                           &child, &iter, 0) == FALSE);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == FALSE);
+  g_assert (child.stamp == 0);
+}
+
+static void
+tree_store_test_iter_parent_invalid (TreeStore     *fixture,
+                                     gconstpointer  user_data)
+{
+  GtkTreeIter iter, child;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == TRUE);
+
+  g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
+                                        &iter, &child) == FALSE);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
+  g_assert (iter.stamp == 0);
+}
+
+/* specific bugs */
+static void
+specific_bug_77977 (void)
+{
+  GtkTreeStore *tree_store;
+  GtkTreeIter iter1, iter2, iter3;
+  GtkTreePath *path;
+  GtkTreeRowReference *row_ref;
+
+  /* Stripped down version of test case for bug 77977 by Damon Chaplin */
+
+  g_test_bug ("77977");
+
+  tree_store = gtk_tree_store_new (1, G_TYPE_STRING);
+
+  gtk_tree_store_append (tree_store, &iter1, NULL);
+  gtk_tree_store_set (tree_store, &iter1, 0, "Window1", -1);
+
+  gtk_tree_store_append (tree_store, &iter2, &iter1);
+  gtk_tree_store_set (tree_store, &iter2, 0, "Table1", -1);
+
+  gtk_tree_store_append (tree_store, &iter3, &iter2);
+  gtk_tree_store_set (tree_store, &iter3, 0, "Button1", -1);
+
+  path = gtk_tree_path_new_from_indices (0, 0, 0, -1);
+  row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (tree_store), path);
+  gtk_tree_path_free (path);
+
+  gtk_tree_store_remove (tree_store, &iter1);
+
+  gtk_tree_row_reference_free (row_ref);
+  g_object_unref (tree_store);
+}
+
+/* main */
+
+void
+register_tree_store_tests (void)
+{
+  /* insertion */
+  g_test_add_func ("/TreeStore/insert-high-values",
+                  tree_store_test_insert_high_values);
+  g_test_add_func ("/TreeStore/append",
+                  tree_store_test_append);
+  g_test_add_func ("/TreeStore/prepend",
+                  tree_store_test_prepend);
+  g_test_add_func ("/TreeStore/insert-after",
+                  tree_store_test_insert_after);
+  g_test_add_func ("/TreeStore/insert-after-NULL",
+                  tree_store_test_insert_after_NULL);
+  g_test_add_func ("/TreeStore/insert-before",
+                  tree_store_test_insert_before);
+  g_test_add_func ("/TreeStore/insert-before-NULL",
+                  tree_store_test_insert_before_NULL);
+
+  /* setting values (FIXME) */
+  g_test_add_func ("/TreeStore/set-gvalue-to-transform",
+                   tree_store_set_gvalue_to_transform);
+
+  /* removal */
+  g_test_add ("/TreeStore/remove-begin", TreeStore, NULL,
+             tree_store_setup, tree_store_test_remove_begin,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/remove-middle", TreeStore, NULL,
+             tree_store_setup, tree_store_test_remove_middle,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/remove-end", TreeStore, NULL,
+             tree_store_setup, tree_store_test_remove_end,
+             tree_store_teardown);
+
+  g_test_add ("/TreeStore/clear", TreeStore, NULL,
+             tree_store_setup, tree_store_test_clear,
+             tree_store_teardown);
+
+  /* reordering */
+  g_test_add ("/TreeStore/reorder", TreeStore, NULL,
+             tree_store_setup, tree_store_test_reorder,
+             tree_store_teardown);
+
+  /* swapping */
+  g_test_add ("/TreeStore/swap-begin", TreeStore, NULL,
+             tree_store_setup, tree_store_test_swap_begin,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/swap-middle-next", TreeStore, NULL,
+             tree_store_setup, tree_store_test_swap_middle_next,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/swap-middle-apart", TreeStore, NULL,
+             tree_store_setup, tree_store_test_swap_middle_apart,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/swap-end", TreeStore, NULL,
+             tree_store_setup, tree_store_test_swap_end,
+             tree_store_teardown);
+  g_test_add_func ("/TreeStore/swap-single",
+                  tree_store_test_swap_single);
+
+  /* moving */
+  g_test_add ("/TreeStore/move-after-from-start", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_after_from_start,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-after-next", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_after_next,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-after-apart", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_after_apart,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-after-end", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_after_end,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-after-from-end", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_after_from_end,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-after-change-ends", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_after_change_ends,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-after-NULL", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_after_NULL,
+             tree_store_teardown);
+  g_test_add_func ("/TreeStore/move-after-single",
+                  tree_store_test_move_after_single);
+
+  g_test_add ("/TreeStore/move-before-next", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_before_next,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-before-apart", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_before_apart,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-before-to-start", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_before_to_start,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-before-from-end", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_before_from_end,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-before-change-ends", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_before_change_ends,
+             tree_store_teardown);
+  g_test_add ("/TreeStore/move-before-NULL", TreeStore, NULL,
+             tree_store_setup, tree_store_test_move_before_NULL,
+             tree_store_teardown);
+  g_test_add_func ("/TreeStore/move-before-single",
+                  tree_store_test_move_before_single);
+
+  /* iter invalidation */
+  g_test_add ("/TreeStore/iter-prev-invalid", TreeStore, NULL,
+              tree_store_setup, tree_store_test_iter_previous_invalid,
+              tree_store_teardown);
+  g_test_add ("/TreeStore/iter-next-invalid", TreeStore, NULL,
+              tree_store_setup, tree_store_test_iter_next_invalid,
+              tree_store_teardown);
+  g_test_add ("/TreeStore/iter-children-invalid", TreeStore, NULL,
+              tree_store_setup, tree_store_test_iter_children_invalid,
+              tree_store_teardown);
+  g_test_add ("/TreeStore/iter-nth-child-invalid", TreeStore, NULL,
+              tree_store_setup, tree_store_test_iter_nth_child_invalid,
+              tree_store_teardown);
+  g_test_add ("/TreeStore/iter-parent-invalid", TreeStore, NULL,
+              tree_store_setup, tree_store_test_iter_parent_invalid,
+              tree_store_teardown);
+
+  /* specific bugs */
+  g_test_add_func ("/TreeStore/bug-77977", specific_bug_77977);
+}
diff --git a/testsuite/gtk/treeview-scrolling.c b/testsuite/gtk/treeview-scrolling.c
new file mode 100644 (file)
index 0000000..77dca9a
--- /dev/null
@@ -0,0 +1,1494 @@
+/* Scrolling test suite for GtkTreeView
+ * Copyright (C) 2006  Kristian Rietveld  <kris@gtk.org>
+ * Copyright (C) 2007  Imendio AB,  Kristian Rietveld
+ * Copyright (C) 2009  Kristian Rietveld  <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Original v1.0 -- December 26, 2006
+ * Conversion to GLib/GTK+ test framework during December, 2007
+ */
+
+
+#include <gtk/gtk.h>
+#include <unistd.h>
+#include <math.h>
+
+#define VIEW_WIDTH 320
+#define VIEW_HEIGHT 240
+
+#define N_ROWS 1000
+#define BIG_N_ROWS N_ROWS * 100
+
+/*
+ * To do:
+ *   - Test that nothing happens if the row is fully visible.
+ *   - The tests are dependent on the theme/font (size measurements,
+ *     chosen paths).
+ *   - Convert to proper GTK+ coding style.
+ *   - Briefly test scrolling in tree stores as well.
+ *
+ * Important:
+ *   - For tests with "mixed height" models, you must ensure that
+ *     there are only two heights used in total and that the rows with
+ *     height A and B are strictly alternating.  The model creation
+ *     functions already do this for you, but take this into account
+ *     when you write a unit test that adds rows to such a created
+ *     model, you must follow this rule otherwise things will break.
+ */
+
+
+/* Constructing models for testing */
+static GtkTreeModel *
+create_model (gboolean constant)
+{
+       int i;
+
+       GtkTreeIter iter;
+       GtkListStore *store;
+
+       store = gtk_list_store_new (1, G_TYPE_STRING);
+
+       for (i = 0; i < N_ROWS; i++) {
+               gtk_list_store_append (store, &iter);
+               if (constant || i % 2 == 0)
+                       gtk_list_store_set (store, &iter, 0, "Foo", -1);
+               else
+                       gtk_list_store_set (store, &iter, 0, "Sliff\nSloff\nBleh", -1);
+       }
+
+       return GTK_TREE_MODEL (store);
+}
+
+static GtkTreeModel *
+create_big_model (gboolean constant)
+{
+       int i;
+
+       GtkTreeIter iter;
+       GtkListStore *store;
+
+       store = gtk_list_store_new (1, G_TYPE_STRING);
+
+       for (i = 0; i < BIG_N_ROWS; i++) {
+               gtk_list_store_append (store, &iter);
+               if (constant || i % 2 == 0)
+                       gtk_list_store_set (store, &iter, 0, "Foo", -1);
+               else
+                       gtk_list_store_set (store, &iter, 0, "Sliff\nSloff\nBleh", -1);
+       }
+
+       return GTK_TREE_MODEL (store);
+}
+
+/*
+ * Fixtures
+ */
+
+typedef struct
+{
+       GtkWidget *window;
+       GtkWidget *tree_view;
+}
+ScrollFixture;
+
+static void
+scroll_fixture_setup (ScrollFixture *fixture,
+                     GtkTreeModel  *model,
+                     gconstpointer  test_data)
+{
+       GtkWidget *sw;
+       GtkCellRenderer *renderer;
+       GtkTreeViewColumn *column;
+
+       fixture->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+       sw = gtk_scrolled_window_new (NULL, NULL);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+                                       GTK_POLICY_NEVER,
+                                       GTK_POLICY_ALWAYS);
+       gtk_container_add (GTK_CONTAINER (fixture->window), sw);
+
+       fixture->tree_view = gtk_tree_view_new_with_model (model);
+       g_object_unref (model);
+       gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (sw), VIEW_WIDTH);
+       gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), VIEW_HEIGHT);
+       gtk_widget_set_size_request (fixture->tree_view, VIEW_WIDTH, VIEW_HEIGHT);
+
+       renderer = gtk_cell_renderer_text_new ();
+       g_object_set (renderer, "editable", TRUE, NULL);
+       column = gtk_tree_view_column_new_with_attributes ("Title",
+                                                          renderer,
+                                                          "text", 0,
+                                                          NULL);
+
+       gtk_tree_view_append_column (GTK_TREE_VIEW (fixture->tree_view), column);
+       gtk_container_add (GTK_CONTAINER (sw), fixture->tree_view);
+}
+
+/* sets up a fixture with a model with constant row heights */
+static void
+scroll_fixture_constant_setup (ScrollFixture *fixture,
+                              gconstpointer  test_data)
+{
+       scroll_fixture_setup (fixture, create_model (TRUE), test_data);
+}
+
+/* sets up a fixture with a model with varying row heights */
+static void
+scroll_fixture_mixed_setup (ScrollFixture *fixture,
+                           gconstpointer  test_data)
+{
+       scroll_fixture_setup (fixture, create_model (FALSE), test_data);
+}
+
+/* sets up a fixture with a large model with constant row heights */
+static void
+scroll_fixture_constant_big_setup (ScrollFixture *fixture,
+                                  gconstpointer  test_data)
+{
+       scroll_fixture_setup (fixture, create_big_model (TRUE), test_data);
+}
+
+/* sets up a fixture with a large model with varying row heights */
+static void
+scroll_fixture_mixed_big_setup (ScrollFixture *fixture,
+                               gconstpointer  test_data)
+{
+       scroll_fixture_setup (fixture, create_big_model (FALSE), test_data);
+}
+
+/* sets up a fixture with only a single row for the "single row scroll" test */
+static void
+scroll_fixture_single_setup (ScrollFixture *fixture,
+                            gconstpointer  test_data)
+{
+       GtkTreeStore *store;
+       GtkTreeIter iter, child;
+
+       store = gtk_tree_store_new (1, G_TYPE_STRING);
+
+       gtk_tree_store_append (store, &iter, NULL);
+       gtk_tree_store_set (store, &iter, 0, "Foo", -1);
+
+       gtk_tree_store_append (store, &child, &iter);
+       gtk_tree_store_set (store, &child, 0, "Two\nLines", -1);
+
+       /* The teardown will also destroy the model */
+       scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), test_data);
+}
+
+/* sets up a fixture with a tree store */
+static void
+scroll_fixture_tree_setup (ScrollFixture *fixture,
+                          gconstpointer   test_data)
+{
+       GtkTreeStore *store;
+       GtkTreeIter iter, child;
+       int i;
+
+       store = gtk_tree_store_new (1, G_TYPE_STRING);
+
+       gtk_tree_store_append (store, &iter, NULL);
+       gtk_tree_store_set (store, &iter, 0, "Root node", -1);
+
+       for (i = 0; i < 5; i++) {
+               gtk_tree_store_append (store, &child, &iter);
+               gtk_tree_store_set (store, &child, 0, "Child node", -1);
+       }
+
+       for (i = 0; i < 5; i++) {
+               gtk_tree_store_append (store, &iter, NULL);
+               gtk_tree_store_set (store, &iter, 0, "Other node", -1);
+       }
+
+       /* The teardown will also destroy the model */
+       scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), test_data);
+}
+
+static void
+scroll_fixture_mixed_tree_setup (ScrollFixture *fixture,
+                                gconstpointer   test_data)
+{
+       GtkTreeStore *store;
+       GtkTreeIter iter, child;
+       int i;
+
+       store = gtk_tree_store_new (1, G_TYPE_STRING);
+
+       gtk_tree_store_append (store, &iter, NULL);
+       gtk_tree_store_set (store, &iter, 0, "Root\nnode", -1);
+
+       for (i = 0; i < 5; i++) {
+               gtk_tree_store_append (store, &child, &iter);
+               if (i % 2 != 0)
+                       gtk_tree_store_set (store, &child, 0, "Child node", -1);
+               else
+                       gtk_tree_store_set (store, &child,
+                                           0, "Child\nnode", -1);
+       }
+
+       for (i = 0; i < 5; i++) {
+               gtk_tree_store_append (store, &iter, NULL);
+               if (i % 2 == 0)
+                       gtk_tree_store_set (store, &iter, 0, "Other node", -1);
+               else
+                       gtk_tree_store_set (store, &iter, 0, "Other\nnode", -1);
+       }
+
+       /* The teardown will also destroy the model */
+       scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), test_data);
+}
+
+static void
+scroll_fixture_teardown (ScrollFixture *fixture,
+                        gconstpointer  test_data)
+{
+       gtk_widget_destroy (fixture->window);
+}
+
+/*
+ * Position check and helpers.
+ */
+enum Pos
+{
+       POS_TOP,
+       POS_CENTER,
+       POS_BOTTOM
+};
+
+static int
+get_row_start_for_index (GtkTreeView *tree_view, int index)
+{
+       gint height1, height2;
+       gint row_start;
+       GtkTreePath *path;
+       GdkRectangle rect;
+
+       path = gtk_tree_path_new_from_indices (0, -1);
+       gtk_tree_view_get_background_area (tree_view, path, NULL, &rect);
+       height1 = rect.height;
+
+       gtk_tree_path_next (path);
+       gtk_tree_view_get_background_area (tree_view, path, NULL, &rect);
+       height2 = rect.height;
+       gtk_tree_path_free (path);
+
+       row_start = (index / 2) * height1 + (index / 2) * height2;
+       if (index % 2)
+               row_start += height1;
+
+       return row_start;
+}
+
+static enum Pos
+get_pos_from_path (GtkTreeView   *tree_view,
+                  GtkTreePath   *path,
+                  gdouble        row_height,
+                  GtkAdjustment *vadjustment)
+{
+       int row_start;
+
+       row_start = get_row_start_for_index (tree_view,
+                                            gtk_tree_path_get_indices (path)[0]);
+
+       if (row_start + row_height < gtk_adjustment_get_page_size (vadjustment))
+               return POS_TOP;
+
+       if (row_start >= gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment))
+               return POS_BOTTOM;
+
+       return POS_CENTER;
+}
+
+static void
+assert_position_with_align (GtkTreeView  *tree_view,
+                            enum Pos      pos,
+                            gint          row_y,
+                            gint          row_start,
+                            gdouble       row_height,
+                            gdouble       row_align)
+{
+       GtkAdjustment *vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (tree_view));
+
+       /* Switch on row-align: 0.0, 0.5, 1.0 */
+       switch ((int)(row_align * 2.)) {
+       case 0:
+               if (pos == POS_TOP || pos == POS_CENTER) {
+                       /* The row in question is the first row
+                        * in the view.
+                        *    - rect.y should be zero
+                        *    - dy should be equal to the top
+                        *      y coordinate of the row.
+                        */
+                       g_assert (row_y == 0);
+                       g_assert (gtk_adjustment_get_value (vadjustment) == row_start);
+               } else {
+                       /* The row can be anywhere at the last
+                        * page of the tree view.
+                        *   - dy is set to the start of the
+                        *     last page.
+                        */
+                       g_assert (gtk_adjustment_get_value (vadjustment) == gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment));
+               }
+               break;
+
+       case 1:
+               /* 0.5 */
+               if (pos == POS_TOP
+                   && row_start < (gtk_adjustment_get_page_size (vadjustment) - row_height) / 2) {
+                       /* For the first half of the top view we can't
+                        * center the row in the view, instead we
+                        * show the first page.
+                        *   - dy should be zero
+                        */
+                       g_assert (gtk_adjustment_get_value (vadjustment) == 0);
+               } else if (pos == POS_BOTTOM
+                          && row_start + row_height >= gtk_adjustment_get_upper (vadjustment) - (gtk_adjustment_get_page_size (vadjustment) - row_height) / 2) {
+                       /* For the last half of the bottom view we
+                        * can't center the row in the view, instead
+                        * we show the last page.
+                        *   - dy should be the start of the 
+                        *     last page.
+                        */
+                       g_assert (gtk_adjustment_get_value (vadjustment) == gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment));
+               } else {
+                       /* The row is located in the middle of
+                        * the view.
+                        *    - top y coordinate is equal to
+                        *      middle of the view minus
+                        *      half the height of the row.
+                        *      (ie. the row's center is at the
+                        *       center of the view).
+                        */
+                       gdouble middle = (gtk_adjustment_get_page_size (vadjustment) - row_height) / 2.0;
+                       g_assert (row_y == ceil (middle) || row_y == floor (middle));
+               }
+               break;
+
+       case 2:
+               /* 1.0 */
+               if (pos == POS_TOP) {
+                       /* The row can be anywhere on the
+                        * first page of the tree view.
+                        *   - dy is zero.
+                        */
+                       g_assert (gtk_adjustment_get_value (vadjustment) == 0);
+               } else if (pos == POS_CENTER || pos == POS_BOTTOM) {
+                       /* The row is the last row visible in the
+                        * view.
+                        *   - rect.y is set to the top of the
+                        *     last row.
+                        *   - row_start is greater than page_size
+                        *     (ie we are not on the first page).
+                        *   - dy is greater than zero
+                        */
+                       g_assert (row_start >= gtk_adjustment_get_page_size (vadjustment)
+                                 || row_start + row_height >= gtk_adjustment_get_page_size (vadjustment));
+                       g_assert (row_y == gtk_adjustment_get_page_size (vadjustment) - row_height);
+               }
+               break;
+       }
+}
+
+static void
+assert_position_without_align (GtkTreeView *tree_view,
+                               gdouble      row_start,
+                               gdouble      row_height)
+{
+  GtkAdjustment *vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (tree_view));
+
+  /* Without align the tree view does as less work as possible,
+   * so basically we only have to check whether the row
+   * is visible on the screen.
+   */
+  g_assert (gtk_adjustment_get_value (vadjustment) <= row_start);
+  g_assert (gtk_adjustment_get_value (vadjustment) + gtk_adjustment_get_page_size (vadjustment) >= row_start + row_height);
+}
+
+static void
+test_position (GtkTreeView *tree_view,
+              GtkTreePath *path,
+              gboolean     use_align,
+              gdouble      row_align)
+{
+       gint pos;
+       gchar *path_str;
+       GdkRectangle rect;
+       GtkTreeModel *model;
+       gint row_start;
+
+       /* Get the location of the path we scrolled to */
+       gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
+                                          path, NULL, &rect);
+
+       row_start = get_row_start_for_index (GTK_TREE_VIEW (tree_view),
+                                            gtk_tree_path_get_indices (path)[0]);
+
+       /* Ugh */
+       pos = get_pos_from_path (GTK_TREE_VIEW (tree_view),
+                                path, rect.height,
+                                gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (tree_view)));
+
+       /* This is only tested for during test_single() */
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+       if (gtk_tree_model_iter_n_children (model, NULL) == 1) {
+                GtkAllocation allocation;
+               GtkTreePath *tmppath;
+
+               /* Test nothing is dangling at the bottom; read
+                * description for test_single() for more information.
+                */
+
+               /* FIXME: hardcoded width */
+                gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
+               if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree_view), 0, allocation.height - 30, &tmppath, NULL, NULL, NULL)) {
+                       g_assert_not_reached ();
+                       gtk_tree_path_free (tmppath);
+               }
+       }
+
+       path_str = gtk_tree_path_to_string (path);
+       if (use_align) {
+               assert_position_with_align (tree_view, pos, rect.y,
+                                            row_start, rect.height, row_align);
+       } else {
+               assert_position_without_align (tree_view, row_start, rect.height);
+       }
+
+       g_free (path_str);
+}
+
+/*
+ * Scrolling code
+ */
+
+
+/* Testing scrolling to various positions with various alignments */
+
+static void
+ensure_layout (void)
+{
+        /* HACK: sleep for more than one frame, to give the paint clock
+         * time to prepare the new layout */
+        g_usleep (100 * 1000);
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+}
+
+static void
+scroll (ScrollFixture *fixture,
+       GtkTreePath   *path,
+       gboolean       use_align,
+       gdouble        row_align)
+{
+       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view), path,
+                                 NULL, FALSE);
+       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
+                                     path, NULL,
+                                     use_align, row_align, 0.0);
+
+       gtk_widget_show_all (fixture->window);
+
+        ensure_layout ();
+       test_position (GTK_TREE_VIEW (fixture->tree_view), path,
+                      use_align, row_align);
+}
+
+static void
+scroll_no_align (ScrollFixture *fixture,
+                gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll (fixture, path, FALSE, 0.0);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_align_0_0 (ScrollFixture *fixture,
+                 gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll (fixture, path, TRUE, 0.0);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_align_0_5 (ScrollFixture *fixture,
+                 gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll (fixture, path, TRUE, 0.5);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_align_1_0 (ScrollFixture *fixture,
+                 gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll (fixture, path, TRUE, 1.0);
+       gtk_tree_path_free (path);
+}
+
+
+static void
+scroll_after_realize (ScrollFixture *fixture,
+                     GtkTreePath   *path,
+                     gboolean       use_align,
+                     gdouble        row_align)
+{
+       gtk_widget_show_all (fixture->window);
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view), path,
+                                 NULL, FALSE);
+       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
+                                     path, NULL,
+                                     use_align, row_align, 0.0);
+
+        ensure_layout ();
+       test_position (GTK_TREE_VIEW (fixture->tree_view), path,
+                      use_align, row_align);
+}
+
+static void
+scroll_after_no_align (ScrollFixture *fixture,
+                      gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll_after_realize (fixture, path, FALSE, 0.0);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_after_align_0_0 (ScrollFixture *fixture,
+                       gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll_after_realize (fixture, path, TRUE, 0.0);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_after_align_0_5 (ScrollFixture *fixture,
+                       gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll_after_realize (fixture, path, TRUE, 0.5);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_after_align_1_0 (ScrollFixture *fixture,
+                       gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll_after_realize (fixture, path, TRUE, 1.0);
+       gtk_tree_path_free (path);
+}
+
+
+static void
+scroll_both_realize (ScrollFixture *fixture,
+                    GtkTreePath   *path,
+                    gboolean       use_align,
+                    gdouble        row_align)
+{
+       GtkTreePath *end;
+
+       gtk_widget_show_all (fixture->window);
+
+       /* Scroll to end */
+       end = gtk_tree_path_new_from_indices (999, -1);
+
+       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view), end,
+                                 NULL, FALSE);
+       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
+                                     end, NULL,
+                                     use_align, row_align, 0.0);
+       gtk_tree_path_free (end);
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       /* Scroll to final position */
+       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view), path,
+                                 NULL, FALSE);
+       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
+                                     path, NULL,
+                                     use_align, row_align, 0.0);
+
+        ensure_layout ();
+       test_position (GTK_TREE_VIEW (fixture->tree_view), path,
+                      use_align, row_align);
+}
+
+static void
+scroll_both_no_align (ScrollFixture *fixture,
+                     gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll_both_realize (fixture, path, FALSE, 0.0);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_both_align_0_0 (ScrollFixture *fixture,
+                      gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll_both_realize (fixture, path, TRUE, 0.0);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_both_align_0_5 (ScrollFixture *fixture,
+                      gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll_both_realize (fixture, path, TRUE, 0.5);
+       gtk_tree_path_free (path);
+}
+
+static void
+scroll_both_align_1_0 (ScrollFixture *fixture,
+                      gconstpointer  test_data)
+{
+       GtkTreePath *path;
+
+       path = gtk_tree_path_new_from_string (test_data);
+       scroll_both_realize (fixture, path, TRUE, 1.0);
+       gtk_tree_path_free (path);
+}
+
+/* Testing scrolling to a newly created row */
+static void
+create_new_row (GtkListStore *store,
+               int           n,
+               GtkTreeIter  *iter)
+{
+       switch (n) {
+               case 0:
+                       /* Prepend a row */
+                       gtk_list_store_prepend (store, iter);
+                       break;
+
+                case 3:
+                       /* Add a row in the middle of the visible area */
+                       gtk_list_store_insert (store, iter, 3);
+                       break;
+
+               case 4:
+                       /* Add a row in the middle of the visible area */
+                       gtk_list_store_insert (store, iter, 4);
+                       break;
+
+                case 5:
+                       /* Add a row which is not completely visible */
+                       gtk_list_store_insert (store, iter, 5);
+                       break;
+
+               case 8:
+                       /* Add a row which is not completely visible */
+                       gtk_list_store_insert (store, iter, 8);
+                       break;
+
+               case 500:
+                       /* Add a row in the middle */
+                       gtk_list_store_insert (store, iter, 500);
+                       break;
+
+               case 999:
+                       /* Append a row */
+                       gtk_list_store_append (store, iter);
+                       break;
+       }
+
+       gtk_list_store_set (store, iter, 0, "New...", -1);
+}
+
+static void
+scroll_new_row_editing_started (GtkCellRenderer *cell,
+                               GtkCellEditable *editable,
+                               const char      *path,
+                               gpointer         user_data)
+{
+       GtkWidget **widget = user_data;
+
+       *widget = GTK_WIDGET (editable);
+}
+
+static void
+test_editable_position (GtkWidget   *tree_view,
+                       GtkWidget   *editable,
+                       GtkTreePath *cursor_path)
+{
+        GtkAllocation allocation;
+       GdkRectangle rect;
+
+       gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
+                                          cursor_path, NULL, &rect);
+
+       /* There are all in bin_window coordinates */
+        gtk_widget_get_allocation (editable, &allocation);
+        g_assert (allocation.y == rect.y + ((rect.height - allocation.height) / 2));
+}
+
+static void
+scroll_new_row (ScrollFixture *fixture,
+               gconstpointer  test_data)
+{
+       GtkTreeIter scroll_iter;
+       GtkTreePath *scroll_path;
+       GtkTreeModel *model;
+       GList *renderers;
+       GtkTreeViewColumn *column;
+       GtkWidget *editable;
+
+       /* The aim of this test is creating a new row at several places,
+        * and immediately put the cursor on it.  TreeView should correctly
+        * scroll to the row and show the editable widget.
+        *
+        * See #81627.
+        */
+
+       g_test_bug ("81627");
+
+       gtk_widget_show_all (fixture->window);
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       /* Create the new row and scroll to it */
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view));
+       create_new_row (GTK_LIST_STORE (model), GPOINTER_TO_INT (test_data),
+                       &scroll_iter);
+
+       /* Set up a signal handler to acquire the editable widget */
+       column = gtk_tree_view_get_column (GTK_TREE_VIEW (fixture->tree_view), 0);
+       renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
+
+       g_signal_connect (G_OBJECT (renderers->data), "editing-started",
+                         G_CALLBACK (scroll_new_row_editing_started),
+                         &editable);
+
+       /* Now set the cursor on the path and start editing */
+       scroll_path = gtk_tree_model_get_path (model, &scroll_iter);
+       gtk_tree_view_set_cursor (GTK_TREE_VIEW (fixture->tree_view),
+                                 scroll_path,
+                                 column,
+                                 TRUE);
+
+        ensure_layout ();
+
+       /* Test position */
+       test_position (GTK_TREE_VIEW (fixture->tree_view), scroll_path,
+                      FALSE, 0.0);
+       test_editable_position (fixture->tree_view, editable, scroll_path);
+
+       gtk_tree_path_free (scroll_path);
+}
+
+static void
+scroll_new_row_tree (ScrollFixture *fixture,
+                    gconstpointer  test_data)
+{
+       GtkTreeModel *model;
+       GtkAdjustment *vadjustment;
+       int i;
+
+       /* The goal of this test is to append new rows at the end of a tree
+        * store and immediately scroll to them.  If there is a parent
+        * node with a couple of childs in the "area above" to explore,
+        * this used to lead to unexpected results due to a bug.
+        *
+        * This issue has been reported by Miroslav Rajcic on
+        * gtk-app-devel-list:
+        * http://mail.gnome.org/archives/gtk-app-devel-list/2008-December/msg00068.html
+        */
+
+       gtk_widget_show_all (fixture->window);
+
+       gtk_tree_view_expand_all (GTK_TREE_VIEW (fixture->tree_view));
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view));
+       vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (fixture->tree_view));
+
+       for (i = 0; i < 5; i++) {
+               GtkTreeIter scroll_iter;
+               GtkTreePath *scroll_path;
+
+               gtk_tree_store_append (GTK_TREE_STORE (model), &scroll_iter,
+                                      NULL);
+               gtk_tree_store_set (GTK_TREE_STORE (model), &scroll_iter,
+                                   0, "New node", -1);
+
+               scroll_path = gtk_tree_model_get_path (model, &scroll_iter);
+               gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view),
+                                             scroll_path, NULL, FALSE, 0.0, 0.0);
+               gtk_tree_path_free (scroll_path);
+
+                ensure_layout ();
+
+               /* Test position, the scroll bar must be at the end */
+               g_assert (gtk_adjustment_get_value (vadjustment) == gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment));
+       }
+}
+
+/* Test for GNOME bugzilla bug 359231; tests "recovery when removing a bunch of
+ * rows at the bottom.
+ */
+static void
+test_bug316689 (ScrollFixture *fixture,
+               gconstpointer  test_data)
+{
+       GtkTreeIter iter;
+       GtkTreePath *path;
+       GtkAdjustment *vadjustment;
+       GtkTreeModel *model;
+
+       /* The aim of this test is to scroll to the bottom of a TreeView,
+        * remove at least one page_size of items and check if TreeView
+        * correctly corrects the scroll bar (else they will look "broken").
+        *
+        * See #316689.
+        */
+
+       g_test_bug ("316689");
+
+       /* Scroll to some place close to the end */
+       path = gtk_tree_path_new_from_indices (N_ROWS - 4, -1);
+       scroll (fixture, path, FALSE, 0.0);
+       gtk_tree_path_free (path);
+
+       /* No need for a while events pending loop here, scroll() does this for us.
+        *
+        * We now remove a bunch of rows, wait for events to process and then
+        * check the adjustments to see if the TreeView gracefully recovered.
+        */
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view));
+
+       while (gtk_tree_model_iter_nth_child (model, &iter, NULL, N_ROWS - 15))
+               gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (fixture->tree_view));
+
+       g_assert (gtk_adjustment_get_value (vadjustment) + gtk_adjustment_get_page_size (vadjustment) <= gtk_adjustment_get_upper (vadjustment));
+       g_assert (gtk_adjustment_get_value (vadjustment) == gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment));
+}
+
+
+/* Test for GNOME bugzilla bug 359231 */
+static void
+test_bug359231 (void)
+{
+       int i;
+       int height1, height2;
+       GtkTreePath *path;
+       GtkTreeIter iter, child;
+       GtkTreeStore *store;
+       GdkRectangle rect;
+       ScrollFixture *fixture;
+
+       /* See #359231. */
+       g_test_bug ("359231");
+
+       /* Create model (GtkTreeStore in this case) */
+       store = gtk_tree_store_new (1, G_TYPE_STRING);
+
+       gtk_tree_store_append (store, &iter, NULL);
+       gtk_tree_store_set (store, &iter, 0, "Foo", -1);
+
+       for (i = 0; i < 4; i++) {
+               gtk_tree_store_append (store, &child, &iter);
+               gtk_tree_store_set (store, &child, 0, "Two\nLines", -1);
+       }
+       
+       fixture = g_new0 (ScrollFixture, 1);
+       scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), NULL);
+       gtk_widget_show_all (fixture->window);
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       /* Prepend some rows at the top, expand */
+       gtk_tree_store_prepend (store, &iter, NULL);
+       gtk_tree_store_set (store, &iter, 0, "Foo", -1);
+
+       gtk_tree_store_prepend (store, &child, &iter);
+       gtk_tree_store_set (store, &child, 0, "Two\nLines", -1);
+
+       gtk_tree_view_expand_all (GTK_TREE_VIEW (fixture->tree_view));
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       /* Test if height of row 0:0 is correct */
+       path = gtk_tree_path_new_from_indices (0, -1);
+       gtk_tree_view_get_background_area (GTK_TREE_VIEW (fixture->tree_view),
+                                          path, NULL, &rect);
+       height1 = rect.height;
+
+       gtk_tree_path_down (path);
+       gtk_tree_view_get_background_area (GTK_TREE_VIEW (fixture->tree_view),
+                                          path, NULL, &rect);
+       height2 = rect.height;
+       gtk_tree_path_free (path);
+
+       g_assert (height2 > height1);
+
+       /* Clean up; the tear down also cleans up the model */
+       scroll_fixture_teardown (fixture, NULL);
+}
+
+/* Test for GNOME bugzilla bug 93584.  We add 150 rows to an existing
+ * small model, and scroll to one of these with alignment.
+ */
+static void
+test_bug93584 (ScrollFixture *fixture,
+              gconstpointer  test_data)
+{
+       int row, i;
+       GtkTreeStore *store;
+       GtkTreePath *path;
+
+       g_test_bug ("93584");
+
+       /* Mimic state as in original test case */
+       g_signal_connect (G_OBJECT (fixture->tree_view), "realize",
+                         G_CALLBACK (gtk_tree_view_expand_all), NULL);
+       gtk_widget_show_all (fixture->window);
+
+       store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
+
+       /* Add 150 rows */
+       for (i = 0; i < 150; i++) {
+               GtkTreeIter iter;
+
+               gtk_tree_store_append (store, &iter, NULL);
+               gtk_tree_store_set (store, &iter, 0, "Row", -1);
+       }
+
+       row = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
+       row -= 20;
+
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       path = gtk_tree_path_new_from_indices (row, -1);
+       scroll (fixture, path, TRUE, 0.5);
+       gtk_tree_path_free (path);
+}
+
+/* GNOME bugzilla bug 111500.  Expand a row and immediately scroll
+ * to its first child.  Make sure that expansion happens in currently
+ * invisible area.
+ */
+static void
+test_bug111500 (ScrollFixture *fixture,
+               gconstpointer  test_data)
+{
+       int i, len;
+       GtkTreeStore *store;
+       GtkTreeIter parent;
+       GtkTreePath *path;
+
+       g_test_bug ("111500");
+
+       gtk_widget_show_all (fixture->window);
+
+       /* Make sure all events have been processed and the window
+        * is visible.
+        */
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       /* Further prepare model */
+       store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
+
+       for (i = 0; i < 15; i++) {
+               GtkTreeIter iter;
+
+               gtk_tree_store_append (store, &iter, NULL);
+               gtk_tree_store_set (store, &iter, 0, "Other node", -1);
+       }
+
+       len = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
+       gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &parent,
+                                      NULL, len - 1);
+
+       for (i = 0; i < 5; i++) {
+               GtkTreeIter iter;
+
+               gtk_tree_store_append (store, &iter, &parent);
+               gtk_tree_store_set (store, &iter, 0, "Row", -1);
+       }
+
+       path = gtk_tree_path_new_from_indices (len - 1, -1);
+       gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view),
+                                 path, FALSE);
+
+       gtk_tree_path_down (path);
+
+       scroll (fixture, path, FALSE, 0.5);
+       gtk_tree_path_free (path);
+}
+
+static void
+test_bug111500_mixed (ScrollFixture *fixture,
+                     gconstpointer  test_data)
+{
+       int i, len;
+       GtkTreeStore *store;
+       GtkTreeIter parent;
+       GtkTreePath *path;
+
+       g_test_bug ("111500");
+
+       gtk_widget_show_all (fixture->window);
+
+       /* Make sure all events have been processed and the window
+        * is visible.
+        */
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       /* Further prepare model */
+       store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
+
+       for (i = 0; i < 15; i++) {
+               GtkTreeIter iter;
+
+               gtk_tree_store_append (store, &iter, NULL);
+               if (i % 2 == 0)
+                       gtk_tree_store_set (store, &iter, 0, "Other node", -1);
+               else
+                       gtk_tree_store_set (store, &iter, 0, "Other\nnode", -1);
+       }
+
+       len = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
+       gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &parent,
+                                      NULL, len - 1);
+
+       for (i = 0; i < 5; i++) {
+               GtkTreeIter iter;
+
+               gtk_tree_store_append (store, &iter, &parent);
+               if (i % 2 != 0)
+                       gtk_tree_store_set (store, &iter, 0, "Row", -1);
+               else
+                       gtk_tree_store_set (store, &iter, 0, "Row\nRow", -1);
+       }
+
+       path = gtk_tree_path_new_from_indices (len - 1, -1);
+       gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view),
+                                 path, FALSE);
+
+       gtk_tree_path_down (path);
+
+       scroll (fixture, path, FALSE, 0.5);
+       gtk_tree_path_free (path);
+}
+
+/* Test for GNOME bugzilla bug 163214.  Invalidate a couple of rows,
+ * then scroll to one of these.
+ */
+static void
+test_bug163214 (ScrollFixture *fixture,
+               gconstpointer  test_data)
+{
+       int i;
+       GtkListStore *store;
+       GtkTreePath *path;
+
+       g_test_bug ("163214");
+
+       gtk_widget_show_all (fixture->window);
+
+       /* Make sure all events have been processed and the window
+        * is visible.
+        */
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
+
+       /* Invalidate a page of rows */
+       for (i = 100; i < 110; i++) {
+               GtkTreeIter iter;
+
+               gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter,
+                                              NULL, i);
+               gtk_list_store_set (store, &iter, 0, "Row", -1);
+       }
+
+       /* Then scroll to that page. */
+       path = gtk_tree_path_new_from_indices (105, -1);
+       scroll (fixture, path, TRUE, 0.5);
+       gtk_tree_path_free (path);
+
+       /* Make sure all events have been processed and the window
+        * is visible.
+        */
+       while (gtk_events_pending ())
+               gtk_main_iteration ();
+
+       store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)));
+
+       /* Invalidate a page of rows */
+       for (i = 300; i < 310; i++) {
+               GtkTreeIter iter;
+
+               gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter,
+                                              NULL, i);
+               gtk_list_store_set (store, &iter, 0, "Row", -1);
+       }
+
+       /* Then scroll to the first row */
+       path = gtk_tree_path_new_from_indices (0, -1);
+       scroll (fixture, path, TRUE, 0.5);
+       gtk_tree_path_free (path);
+}
+
+/* Infrastructure for automatically adding tests */
+enum
+{
+       BEFORE,
+       AFTER,
+       BOTH
+};
+
+static const char *
+test_type_string (int test_type)
+{
+       switch (test_type) {
+               case BEFORE:
+                       return "before-realize";
+
+               case AFTER:
+                       return "after-realize";
+
+               case BOTH:
+                       return "both";
+       }
+
+       return "???";
+}
+
+static char *
+align_string (gboolean use_align,
+             gdouble  row_align)
+{
+       char *ret;
+
+       if (!use_align)
+               return g_strdup ("no-align");
+
+       ret = g_strdup_printf ("align-%1.1f", row_align);
+       return ret;
+}
+
+static void
+add_test (const char *path,
+         gboolean    mixed,
+         int         test_type,
+         gboolean    use_align,
+         gdouble     row_align,
+         void (* setup) (ScrollFixture *, gconstpointer),
+         void (* scroll_func) (ScrollFixture *, gconstpointer))
+{
+       gchar *test_path;
+       gchar *align;
+
+       align = align_string (use_align, row_align);
+
+       test_path = g_strdup_printf ("/TreeView/scrolling/%s/%s-height/path-%s-%s",
+                                    test_type_string (test_type),
+                                    mixed ? "mixed" : "constant",
+                                    path, align);
+       g_free (align);
+
+       g_test_add (test_path, ScrollFixture, path,
+                   setup, scroll_func, scroll_fixture_teardown);
+
+       g_free (test_path);
+}
+
+static void
+add_tests (gboolean mixed,
+          int test_type,
+          gboolean use_align,
+          gdouble  row_align,
+          void (*scroll_func) (ScrollFixture *, gconstpointer))
+{
+       void (* setup) (ScrollFixture *, gconstpointer);
+
+       if (mixed)
+               setup = scroll_fixture_mixed_setup;
+       else
+               setup = scroll_fixture_constant_setup;
+
+       add_test ("0", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("2", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("5", mixed, test_type, use_align, row_align, setup, scroll_func);
+       /* We scroll to 8 to test a partial visible row.  The 8 is
+        * based on my font setting of "Vera Sans 11" and
+        * the separators set to 0.  (This should be made dynamic; FIXME).
+        */
+       add_test ("8", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("10", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("250", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("500", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("750", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("990", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("991", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("995", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("997", mixed, test_type, use_align, row_align, setup, scroll_func);
+       add_test ("999", mixed, test_type, use_align, row_align, setup, scroll_func);
+}
+
+int
+main (int argc, char **argv)
+{
+       gtk_test_init (&argc, &argv);
+
+       /* Scrolls before realization */
+       add_tests (FALSE, BEFORE, FALSE, 0.0, scroll_no_align);
+       if (g_test_thorough ())
+               add_tests (TRUE, BEFORE, FALSE, 0.0, scroll_no_align);
+
+       add_tests (FALSE, BEFORE, TRUE, 0.0, scroll_align_0_0);
+       if (g_test_thorough ())
+               add_tests (TRUE, BEFORE, TRUE, 0.0, scroll_align_0_0);
+
+       add_tests (FALSE, BEFORE, TRUE, 0.5, scroll_align_0_5);
+       if (g_test_thorough ())
+               add_tests (TRUE, BEFORE, TRUE, 0.5, scroll_align_0_5);
+
+       add_tests (FALSE, BEFORE, TRUE, 1.0, scroll_align_1_0);
+       if (g_test_thorough ())
+               add_tests (TRUE, BEFORE, TRUE, 1.0, scroll_align_1_0);
+
+       /* Scrolls after realization */
+       add_tests (FALSE, AFTER, FALSE, 0.0, scroll_after_no_align);
+       if (g_test_thorough ())
+               add_tests (TRUE, AFTER, FALSE, 0.0, scroll_after_no_align);
+
+       add_tests (FALSE, AFTER, TRUE, 0.0, scroll_after_align_0_0);
+       if (g_test_thorough ())
+               add_tests (TRUE, AFTER, TRUE, 0.0, scroll_after_align_0_0);
+
+       add_tests (FALSE, AFTER, TRUE, 0.5, scroll_after_align_0_5);
+       if (g_test_thorough ())
+               add_tests (TRUE, AFTER, TRUE, 0.5, scroll_after_align_0_5);
+
+       add_tests (FALSE, AFTER, TRUE, 1.0, scroll_after_align_1_0);
+       if (g_test_thorough ())
+               add_tests (TRUE, AFTER, TRUE, 1.0, scroll_after_align_1_0);
+
+       /* Scroll to end before realization, to a real position after */
+       if (g_test_thorough ()) {
+               add_tests (FALSE, BOTH, FALSE, 0.0, scroll_both_no_align);
+               add_tests (TRUE, BOTH, FALSE, 0.0, scroll_both_no_align);
+
+               add_tests (FALSE, BOTH, TRUE, 0.0, scroll_both_align_0_0);
+               add_tests (TRUE, BOTH, TRUE, 0.0, scroll_both_align_0_0);
+
+               add_tests (FALSE, BOTH, TRUE, 0.5, scroll_both_align_0_5);
+               add_tests (TRUE, BOTH, TRUE, 0.5, scroll_both_align_0_5);
+
+               add_tests (FALSE, BOTH, TRUE, 1.0, scroll_both_align_1_0);
+               add_tests (TRUE, BOTH, TRUE, 1.0, scroll_both_align_1_0);
+       }
+
+       /* Test different alignments in view with single row */
+       g_test_add ("/TreeView/scrolling/single-row/no-align",
+                   ScrollFixture, "0",
+                   scroll_fixture_single_setup,
+                   scroll_no_align,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/single-row/align-0.0",
+                   ScrollFixture, "0",
+                   scroll_fixture_single_setup,
+                   scroll_align_0_0,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/single-row/align-0.5",
+                   ScrollFixture, "0",
+                   scroll_fixture_single_setup,
+                   scroll_align_0_5,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/single-row/align-1.0",
+                   ScrollFixture, "0",
+                   scroll_fixture_single_setup,
+                   scroll_align_1_0,
+                   scroll_fixture_teardown);
+
+       /* Test scrolling in a very large model; also very slow */
+       if (g_test_slow ()) {
+               g_test_add ("/TreeView/scrolling/large-model/constant-height/middle-no-align",
+                           ScrollFixture, "50000",
+                           scroll_fixture_constant_big_setup,
+                           scroll_no_align,
+                           scroll_fixture_teardown);
+               g_test_add ("/TreeView/scrolling/large-model/constant-height/end-no-align",
+                           ScrollFixture, "99999",
+                           scroll_fixture_constant_big_setup,
+                           scroll_no_align,
+                           scroll_fixture_teardown);
+
+               g_test_add ("/TreeView/scrolling/large-model/mixed-height/middle-no-align",
+                           ScrollFixture, "50000",
+                           scroll_fixture_mixed_big_setup,
+                           scroll_no_align,
+                           scroll_fixture_teardown);
+               g_test_add ("/TreeView/scrolling/large-model/mixed-height/end-no-align",
+                           ScrollFixture, "99999",
+                           scroll_fixture_mixed_big_setup,
+                           scroll_no_align,
+                           scroll_fixture_teardown);
+       }
+
+       /* Test scrolling to a newly created row */
+       g_test_add ("/TreeView/scrolling/new-row/path-0", ScrollFixture,
+                   GINT_TO_POINTER (0),
+                   scroll_fixture_constant_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/new-row/path-4", ScrollFixture,
+                   GINT_TO_POINTER (4),
+                   scroll_fixture_constant_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+       /* We scroll to 8 to test a partial visible row.  The 8 is
+        * based on my font setting of "Vera Sans 11" and
+        * the separators set to 0.  (This should be made dynamic; FIXME).
+        */
+       g_test_add ("/TreeView/scrolling/new-row/path-8", ScrollFixture,
+                   GINT_TO_POINTER (8),
+                   scroll_fixture_constant_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/new-row/path-500", ScrollFixture,
+                   GINT_TO_POINTER (500),
+                   scroll_fixture_constant_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/new-row/path-999", ScrollFixture,
+                   GINT_TO_POINTER (999),
+                   scroll_fixture_constant_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+
+       g_test_add ("/TreeView/scrolling/new-row/tree", ScrollFixture,
+                   NULL,
+                   scroll_fixture_tree_setup,
+                   scroll_new_row_tree,
+                   scroll_fixture_teardown);
+
+       /* Test scrolling to a newly created row, in a mixed height model */
+       g_test_add ("/TreeView/scrolling/new-row-mixed/path-0", ScrollFixture,
+                   GINT_TO_POINTER (0),
+                   scroll_fixture_mixed_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/new-row-mixed/path-3", ScrollFixture,
+                   GINT_TO_POINTER (3),
+                   scroll_fixture_mixed_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+       /* We scroll to 8 to test a partial visible row.  The 8 is
+        * based on my font setting of "Vera Sans 11" and
+        * the separators set to 0.  (This should be made dynamic; FIXME).
+        */
+       g_test_add ("/TreeView/scrolling/new-row-mixed/path-5", ScrollFixture,
+                   GINT_TO_POINTER (5),
+                   scroll_fixture_mixed_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/new-row-mixed/path-500", ScrollFixture,
+                   GINT_TO_POINTER (500),
+                   scroll_fixture_mixed_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/new-row-mixed/path-999", ScrollFixture,
+                   GINT_TO_POINTER (999),
+                   scroll_fixture_mixed_setup,
+                   scroll_new_row,
+                   scroll_fixture_teardown);
+
+       g_test_add ("/TreeView/scrolling/new-row-mixed/tree", ScrollFixture,
+                   NULL,
+                   scroll_fixture_mixed_tree_setup,
+                   scroll_new_row_tree,
+                   scroll_fixture_teardown);
+
+       /* Misc. tests */
+       g_test_add ("/TreeView/scrolling/specific/bug-316689",
+                       ScrollFixture, NULL,
+                   scroll_fixture_constant_setup, test_bug316689,
+                   scroll_fixture_teardown);
+       g_test_add_func ("/TreeView/scrolling/specific/bug-359231",
+                       test_bug359231);
+       g_test_add ("/TreeView/scrolling/specific/bug-93584",
+                   ScrollFixture, NULL,
+                   scroll_fixture_tree_setup, test_bug93584,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/specific/bug-111500",
+                   ScrollFixture, NULL,
+                   scroll_fixture_tree_setup, test_bug111500,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/specific/bug-111500-mixed",
+                   ScrollFixture, NULL,
+                   scroll_fixture_mixed_tree_setup, test_bug111500_mixed,
+                   scroll_fixture_teardown);
+       g_test_add ("/TreeView/scrolling/specific/bug-163214",
+                   ScrollFixture, NULL,
+                   scroll_fixture_constant_setup, test_bug163214,
+                   scroll_fixture_teardown);
+
+       return g_test_run ();
+}
diff --git a/testsuite/gtk/treeview.c b/testsuite/gtk/treeview.c
new file mode 100644 (file)
index 0000000..34676a5
--- /dev/null
@@ -0,0 +1,243 @@
+/* Basic GtkTreeView unit tests.
+ * Copyright (C) 2009  Kristian Rietveld  <kris@gtk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+static void
+test_bug_546005 (void)
+{
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  GtkTreePath *cursor_path;
+  GtkListStore *list_store;
+  GtkWidget *view;
+
+  /* Tests provided by Bjorn Lindqvist, Paul Pogonyshev */
+  view = gtk_tree_view_new ();
+
+  /* Invalid path on tree view without model */
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
+                            NULL, FALSE);
+  gtk_tree_path_free (path);
+
+  list_store = gtk_list_store_new (1, G_TYPE_STRING);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (view),
+                           GTK_TREE_MODEL (list_store));
+
+  /* Invalid path on tree view with empty model */
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
+                            NULL, FALSE);
+  gtk_tree_path_free (path);
+
+  /* Valid path */
+  gtk_list_store_insert_with_values (list_store, &iter, 0,
+                                     0, "hi",
+                                     -1);
+
+  path = gtk_tree_path_new_from_indices (0, -1);
+  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
+                            NULL, FALSE);
+
+  gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &cursor_path, NULL);
+  //gtk_assert_cmptreepath (cursor_path, ==, path);
+
+  gtk_tree_path_free (path);
+  gtk_tree_path_free (cursor_path);
+
+  /* Invalid path on tree view with model */
+  path = gtk_tree_path_new_from_indices (1, -1);
+  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
+                            NULL, FALSE);
+  gtk_tree_path_free (path);
+}
+
+static void
+test_bug_539377 (void)
+{
+  GtkWidget *view;
+  GtkTreePath *path;
+  GtkListStore *list_store;
+
+  /* Test provided by Bjorn Lindqvist */
+
+  /* Non-realized view, no model */
+  view = gtk_tree_view_new ();
+  g_assert (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), 10, 10, &path,
+                                           NULL, NULL, NULL) == FALSE);
+  g_assert (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), 10, 10,
+                                               &path, NULL) == FALSE);
+
+  /* Non-realized view, with model */
+  list_store = gtk_list_store_new (1, G_TYPE_STRING);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (view),
+                           GTK_TREE_MODEL (list_store));
+
+  g_assert (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), 10, 10, &path,
+                                           NULL, NULL, NULL) == FALSE);
+  g_assert (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), 10, 10,
+                                               &path, NULL) == FALSE);
+}
+
+static void
+test_select_collapsed_row (void)
+{
+  GtkTreeIter child, parent;
+  GtkTreePath *path;
+  GtkTreeStore *tree_store;
+  GtkTreeSelection *selection;
+  GtkWidget *view;
+
+  /* Reported by Michael Natterer */
+  tree_store = gtk_tree_store_new (1, G_TYPE_STRING);
+  view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
+
+  gtk_tree_store_insert_with_values (tree_store, &parent, NULL, 0,
+                                     0, "Parent",
+                                     -1);
+
+  gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0,
+                                     0, "Child",
+                                     -1);
+  gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0,
+                                     0, "Child",
+                                     -1);
+
+
+  /* Try to select a child path. */
+  path = gtk_tree_path_new_from_indices (0, 1, -1);
+  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+
+  /* Check that the parent is not selected. */
+  gtk_tree_path_up (path);
+  g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == FALSE);
+
+  /* Nothing should be selected at this point. */
+  g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 0);
+
+  /* Check that selection really still works. */
+  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
+  g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE);
+  g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
+
+  /* Expand and select child node now. */
+  gtk_tree_path_append_index (path, 1);
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+
+  gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
+  g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE);
+  g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
+
+  gtk_tree_path_free (path);
+}
+
+static gboolean
+test_row_separator_height_func (GtkTreeModel *model,
+                                GtkTreeIter  *iter,
+                                gpointer      data)
+{
+  gboolean ret = FALSE;
+  GtkTreePath *path;
+
+  path = gtk_tree_model_get_path (model, iter);
+  if (gtk_tree_path_get_indices (path)[0] == 2)
+    ret = TRUE;
+  gtk_tree_path_free (path);
+
+  return ret;
+}
+
+static void
+test_row_separator_height (void)
+{
+  int focus_pad, separator_height, height;
+  gboolean wide_separators;
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  GtkListStore *store;
+  GtkWidget *window;
+  GtkWidget *tree_view;
+  GdkRectangle rect, cell_rect;
+
+  store = gtk_list_store_new (1, G_TYPE_STRING);
+  gtk_list_store_insert_with_values (store, &iter, 0, 0, "Row content", -1);
+  gtk_list_store_insert_with_values (store, &iter, 1, 0, "Row content", -1);
+  gtk_list_store_insert_with_values (store, &iter, 2, 0, "Row content", -1);
+  gtk_list_store_insert_with_values (store, &iter, 3, 0, "Row content", -1);
+  gtk_list_store_insert_with_values (store, &iter, 4, 0, "Row content", -1);
+
+  window = gtk_offscreen_window_new ();
+
+  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
+  gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (tree_view),
+                                        test_row_separator_height_func,
+                                        NULL,
+                                        NULL);
+
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+                                               0,
+                                               "Test",
+                                               gtk_cell_renderer_text_new (),
+                                               "text", 0,
+                                               NULL);
+
+  gtk_container_add (GTK_CONTAINER (window), tree_view);
+  gtk_widget_show_all (window);
+
+
+  path = gtk_tree_path_new_from_indices (2, -1);
+  gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
+                                     path, NULL, &rect);
+  gtk_tree_view_get_cell_area (GTK_TREE_VIEW (tree_view),
+                               path, NULL, &cell_rect);
+  gtk_tree_path_free (path);
+
+  gtk_widget_style_get (tree_view,
+                        "focus-padding", &focus_pad,
+                        "wide-separators", &wide_separators,
+                        "separator-height", &separator_height,
+                        NULL);
+
+  if (wide_separators)
+    height = separator_height + 2 * focus_pad;
+  else
+    height = 2 + 2 * focus_pad;
+
+  g_assert_cmpint (rect.height, ==, height);
+  g_assert_cmpint (cell_rect.height, ==, height);
+
+  gtk_widget_destroy (tree_view);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  gtk_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/TreeView/cursor/bug-546005", test_bug_546005);
+  g_test_add_func ("/TreeView/cursor/bug-539377", test_bug_539377);
+  g_test_add_func ("/TreeView/cursor/select-collapsed_row",
+                   test_select_collapsed_row);
+  g_test_add_func ("/TreeView/sizing/row-separator-height",
+                   test_row_separator_height);
+
+  return g_test_run ();
+}
diff --git a/testsuite/gtk/window.c b/testsuite/gtk/window.c
new file mode 100644 (file)
index 0000000..74fa6eb
--- /dev/null
@@ -0,0 +1,361 @@
+#include <gtk/gtk.h>
+
+static gboolean interactive = FALSE;
+
+static gboolean
+stop_main (gpointer data)
+{
+  gtk_main_quit ();
+
+  return G_SOURCE_REMOVE;
+}
+
+static gboolean
+on_draw (GtkWidget *widget, cairo_t *cr)
+{
+  gint i, j;
+
+  for (i = 0; 20 * i < gtk_widget_get_allocated_width (widget); i++)
+    {
+      for (j = 0; 20 * j < gtk_widget_get_allocated_height (widget); j++)
+        {
+          if ((i + j) % 2 == 1)
+            cairo_set_source_rgb (cr, 1., 1., 1.);
+          else
+            cairo_set_source_rgb (cr, 0., 0., 0.);
+
+          cairo_rectangle (cr, 20. * i, 20. *j, 20., 20.);
+          cairo_fill (cr);
+        }
+    }
+
+  return FALSE;
+}
+
+static gboolean
+on_keypress (GtkWidget *widget)
+{
+  gtk_main_quit ();
+
+  return TRUE;
+}
+
+static void
+test_default_size (void)
+{
+  GtkWidget *window;
+  GtkWidget *box;
+  gint w, h;
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  g_signal_connect (window, "draw", G_CALLBACK (on_draw), NULL);
+  if (interactive)
+    g_signal_connect (window, "key-press-event", G_CALLBACK (on_keypress), NULL);
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_container_add (GTK_CONTAINER (window), box);
+
+  /* check that default size is unset initially */
+  gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, -1);
+  g_assert_cmpint (h, ==, -1);
+
+  /* check that setting default size before realize works */
+  gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
+
+  gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 300);
+  g_assert_cmpint (h, ==, 300);
+
+  /* check that the window size is also reported accordingly */
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 300);
+  g_assert_cmpint (h, ==, 300);
+
+  gtk_widget_show_all (window);
+
+  if (!interactive)
+    g_timeout_add (200, stop_main, NULL);
+  gtk_main ();
+
+  /* check that the window and its content actually gets the right size */
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 300);
+  g_assert_cmpint (h, ==, 300);
+
+  g_assert_cmpint (gtk_widget_get_allocated_width (window), ==, 300);
+  g_assert_cmpint (gtk_widget_get_allocated_height (window), ==, 300);
+
+  g_assert_cmpint (gtk_widget_get_allocated_width (box), ==, 300);
+  g_assert_cmpint (gtk_widget_get_allocated_height (box), ==, 300);
+
+  /* check that setting default size after the fact does not change
+   * window size
+   */
+  gtk_window_set_default_size (GTK_WINDOW (window), 100, 600);
+  gtk_window_get_default_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 100);
+  g_assert_cmpint (h, ==, 600);
+
+  if (!interactive)
+    g_timeout_add (200, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 300);
+  g_assert_cmpint (h, ==, 300);
+
+  /* check that even hide/show does not pull in the new default */
+  gtk_widget_hide (window);
+  gtk_widget_show (window);
+
+  if (!interactive)
+    g_timeout_add (200, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 300);
+  g_assert_cmpint (h, ==, 300);
+
+  gtk_widget_destroy (window);
+}
+
+static void
+test_resize (void)
+{
+  GtkWidget *window;
+  GtkWidget *box;
+  gint w, h;
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  g_signal_connect (window, "draw", G_CALLBACK (on_draw), NULL);
+  if (interactive)
+    g_signal_connect (window, "key-press-event", G_CALLBACK (on_keypress), NULL);
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_container_add (GTK_CONTAINER (window), box);
+
+  /* test that resize before show overrides default size */
+  gtk_window_set_default_size (GTK_WINDOW (window), 500, 500);
+
+  gtk_window_resize (GTK_WINDOW (window), 1, 1);
+
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 1);
+  g_assert_cmpint (h, ==, 1);
+
+  gtk_window_resize (GTK_WINDOW (window), 400, 200);
+
+  gtk_widget_show_all (window);
+
+  if (!interactive)
+    g_timeout_add (200, stop_main, NULL);
+  gtk_main ();
+
+  /* test that resize before show works */
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 400);
+  g_assert_cmpint (h, ==, 200);
+
+  /* test that resize after show works, both
+   * for making things bigger and for making things
+   * smaller
+   */
+  gtk_window_resize (GTK_WINDOW (window), 200, 400);
+
+  if (!interactive)
+    g_timeout_add (200, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (w, ==, 200);
+  g_assert_cmpint (h, ==, 400);
+
+  gtk_widget_destroy (window);
+}
+
+static void
+test_resize_popup (void)
+{
+  GtkWidget *window;
+  gint x, y, w, h;
+
+  /* testcase for the dnd window */
+  window = gtk_window_new (GTK_WINDOW_POPUP);
+  gtk_window_set_screen (GTK_WINDOW (window), gdk_screen_get_default ());
+  gtk_window_resize (GTK_WINDOW (window), 1, 1);
+  gtk_window_move (GTK_WINDOW (window), -99, -99);
+
+  gtk_window_get_position (GTK_WINDOW (window), &x, &y);
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (x, ==, -99);
+  g_assert_cmpint (y, ==, -99);
+  g_assert_cmpint (w, ==, 1);
+  g_assert_cmpint (h, ==, 1);
+
+  gtk_widget_show (window);
+
+  g_timeout_add (200, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_position (GTK_WINDOW (window), &x, &y);
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  g_assert_cmpint (x, ==, -99);
+  g_assert_cmpint (y, ==, -99);
+  g_assert_cmpint (w, ==, 1);
+  g_assert_cmpint (h, ==, 1);
+
+  gtk_widget_destroy (window);
+}
+
+static void
+test_show_hide (void)
+{
+  GtkWidget *window;
+  gint w, h, w1, h1;
+
+  g_test_bug ("696882");
+
+  /* test that hide/show does not affect the size */
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  gtk_widget_show (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+
+  gtk_widget_hide (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
+  g_assert_cmpint (w, ==, w1);
+  g_assert_cmpint (h, ==, h1);
+
+  gtk_widget_show (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
+  g_assert_cmpint (w, ==, w1);
+  g_assert_cmpint (h, ==, h1);
+
+  gtk_widget_destroy (window);
+}
+
+static void
+test_show_hide2 (void)
+{
+  GtkWidget *window;
+  gint x, y, w, h, w1, h1;
+
+  g_test_bug ("696882");
+
+  /* test that hide/show does not affect the size,
+   * even when get_position/move is called
+   */
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  gtk_widget_show (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_position (GTK_WINDOW (window), &x, &y);
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  gtk_widget_hide (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
+  g_assert_cmpint (w, ==, w1);
+  g_assert_cmpint (h, ==, h1);
+
+  gtk_window_move (GTK_WINDOW (window), x, y);
+  gtk_widget_show (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
+  g_assert_cmpint (w, ==, w1);
+  g_assert_cmpint (h, ==, h1);
+
+  gtk_widget_destroy (window);
+}
+
+static void
+test_show_hide3 (void)
+{
+  GtkWidget *window;
+  gint x, y, w, h, w1, h1;
+
+  g_test_bug ("696882");
+
+  /* test that hide/show does not affect the size,
+   * even when get_position/move is called and
+   * a default size is set
+   */
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
+
+  gtk_widget_show (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_position (GTK_WINDOW (window), &x, &y);
+  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+  gtk_widget_hide (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
+  g_assert_cmpint (w, ==, w1);
+  g_assert_cmpint (h, ==, h1);
+
+  gtk_window_move (GTK_WINDOW (window), x, y);
+  gtk_widget_show (window);
+
+  g_timeout_add (100, stop_main, NULL);
+  gtk_main ();
+
+  gtk_window_get_size (GTK_WINDOW (window), &w1, &h1);
+  g_assert_cmpint (w, ==, w1);
+  g_assert_cmpint (h, ==, h1);
+
+  gtk_widget_destroy (window);
+}
+
+int
+main (int argc, char *argv[])
+{
+  gint i;
+
+  gtk_test_init (&argc, &argv);
+  g_test_bug_base ("http://bugzilla.gnome.org/");
+
+  for (i = 0; i < argc; i++)
+    {
+      if (g_strcmp0 (argv[i], "--interactive") == 0)
+        interactive = TRUE;
+    }
+
+  g_test_add_func ("/window/default-size", test_default_size);
+  g_test_add_func ("/window/resize", test_resize);
+  g_test_add_func ("/window/resize-popup", test_resize_popup);
+  g_test_add_func ("/window/show-hide", test_show_hide);
+  g_test_add_func ("/window/show-hide2", test_show_hide2);
+  g_test_add_func ("/window/show-hide3", test_show_hide3);
+
+  return g_test_run ();
+}